/// <summary>
        /// Generate sub header Data of BW result
        /// </summary>
        /// <param name="sequenceNumber"></param>
        /// <returns></returns>
        public byte[] GenerateSubHander_BWResult()
        {
            RDP_BW_RESULTS bwresult = RdpbcgrUtility.GenerateBandwidthMeasureResults(AUTO_DETECT_RESPONSE_TYPE.RDP_BW_RESULTS_AFTER_CONNECT, bwStopSequenceNumber, timeDelta, bandwidthMeasurePayloadByteCount);

            byte[] subHeaderbytes = RdpbcgrClient.EncodeNetworkDetectionResponse(bwresult, true);
            return(subHeaderbytes);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Send a Tunnel Data PDU with RDP_NETCHAR_RESULT in its subheader
        /// </summary>
        /// <param name="requestedProtocol"></param>
        /// <param name="sequenceNumber"></param>
        private void SendTunnelDataPdu_NetcharResult(Multitransport_Protocol_value requestedProtocol, ushort sequenceNumber)
        {
            autoDetectedBaseRTT    = (uint)(rttDataStore.responseTime - rttDataStore.requestTime).Milliseconds;
            autoDetectedAverageRTT = (uint)(rttDataStore.responseTime - rttDataStore.requestTime).Milliseconds;
            if (bwDataStore.timeDelta != 0)
            {
                autoDetectedBandwidth = (bwDataStore.byteCount * 8) / bwDataStore.timeDelta;
            }

            RdpemtServer rdpemtServer = rdpemtServerR;

            if (requestedProtocol == Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL)
            {
                rdpemtServer = rdpemtServerL;
            }
            RDP_NETCHAR_RESULT netResult = RdpbcgrUtility.GenerateNetworkCharacteristicsResult(AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_BANDWIDTH_AVERAGERTT, sequenceNumber, autoDetectedBaseRTT, autoDetectedBandwidth, autoDetectedAverageRTT);

            byte[]        reqData       = rdpbcgrServer.EncodeNetworkDetectionRequest(netResult, true);
            List <byte[]> subHdDataList = new List <byte[]>();

            subHdDataList.Add(reqData);
            RDP_TUNNEL_DATA tunnelData = rdpemtServer.CreateTunnelDataPdu(null, subHdDataList);

            rdpemtServer.SendRdpemtPacket(tunnelData);
        }
        /// <summary>
        /// Validate data signature for received PDUs.
        /// </summary>
        /// <param name="dataSignature">The data signature to be validate. This argument can be null.</param>
        /// <param name="data">Data generates the signature. This argument can be null.</param>
        /// <param name="isSalted">Specify if data signature generated with salted MAC.</param>
        /// <returns>If the data signature is valid.</returns>
        internal bool ValidateDataSignature(byte[] dataSignature, byte[] data, bool isSalted)
        {
            byte[] signature = null;

            if (data != null)
            {
                if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT ||
                    encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT ||
                    encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT)
                {
                    if (isSalted)
                    {
                        signature = GenerateSaltedDataSignature(macKey, data, decryptionCount);
                    }
                    else
                    {
                        signature = GenerateNonFIPSDataSignature(macKey, data);
                    }
                }
                else if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_FIPS)
                {
                    signature = GenerateFIPSDataSignature(macKey, data, decryptionCount);
                }
                // else do nothing
            }

            return(RdpbcgrUtility.AreEqual(signature, dataSignature));
        }
 /// <summary>
 /// Reverse all bits of every byte for all bytes of a buffer.
 /// </summary>
 /// <param name="buffer">The buffer to be reversed.</param>
 private static void ReverseEveryByte(byte[] buffer)
 {
     for (int i = 0; i < buffer.Length; ++i)
     {
         buffer[i] = RdpbcgrUtility.ReverseByte(buffer[i]);
     }
 }
        /// <summary>
        /// Generate the FIPS MAC signature for the given data.
        /// </summary>
        /// <param name="macKey">MAC key used for generating MAC signature.</param>
        /// <param name="data">The given Data</param>
        /// <param name="count">The cumulative encryption count, indicating how many encryptions have been
        /// carried out.</param>
        /// <returns>The MAC signature.</returns>
        private static byte[] GenerateFIPSDataSignature(byte[] macKey, byte[] data, Int32 count)
        {
            // MACSignature = First64Bits(HMAC(HMACKey, Data + EncryptionCount))
            byte[]   temp = RdpbcgrUtility.ConcatenateArrays(data, BitConverter.GetBytes(count));
            HMACSHA1 hmac = new HMACSHA1(macKey);

            return(GetFirstNBits(64, hmac.ComputeHash(temp)));
        }
        private void SendClientSecurityExchangePDU()
        {
            // Create random data
            byte[] clientRandom = RdpbcgrUtility.GenerateRandom(RdpbcgrTestData.ClientRandomSize);
            Client_Security_Exchange_Pdu exchangePdu = rdpbcgrClient.CreateSecurityExchangePdu(clientRandom);

            rdpbcgrClient.SendPdu(exchangePdu);
        }
        /// <summary>
        /// Generate the session key for Non-FIPS according to section 5.3.5 Initial Session Key Generation.
        /// </summary>
        /// <param name="clientRandom">The client random generated by client.</param>
        /// <param name="serverRandom">The server random received from server.</param>
        /// <param name="macKey">The computed MACKey.</param>
        /// <param name="clientEncKey">The computed client encrypt key.</param>
        /// <param name="clientDecKey">The computed client decrypt key.</param>
        private static void GenerateNonFIPSSessionKey(byte[] clientRandom,
                                                      byte[] serverRandom,
                                                      out byte[] macKey,
                                                      out byte[] clientEncKey,
                                                      out byte[] clientDecKey)
        {
            // PreMasterSecret = First192Bits(ClientRandom) + First192Bits(ServerRandom)
            byte[] preMasterSecret = RdpbcgrUtility.ConcatenateArrays(GetFirstNBits(192, clientRandom),
                                                                      GetFirstNBits(192, serverRandom));

            // SaltedHash(S, I) = MD5(S + SHA(I + S + ClientRandom + ServerRandom))
            // PreMasterHash(I) = SaltedHash(PremasterSecret, I)
            // MasterSecret = PreMasterHash('A') + PreMasterHash('BB') + PreMasterHash('CCC')
            byte[] Salt1 = SaltedHash(preMasterSecret,
                                      Encoding.ASCII.GetBytes(ConstValue.NON_FIPS_MASTER_SECRET_A),
                                      clientRandom,
                                      serverRandom);
            byte[] Salt2 = SaltedHash(preMasterSecret,
                                      Encoding.ASCII.GetBytes(ConstValue.NON_FIPS_MASTER_SECRET_BB),
                                      clientRandom,
                                      serverRandom);
            byte[] Salt3 = SaltedHash(preMasterSecret,
                                      Encoding.ASCII.GetBytes(ConstValue.NON_FIPS_MASTER_SECRET_CCC),
                                      clientRandom,
                                      serverRandom);
            byte[] masterSecret = RdpbcgrUtility.ConcatenateArrays(Salt1, Salt2, Salt3);

            // MasterHash(I) = SaltedHash(MasterSecret, I)
            // SessionKeyBlob = MasterHash('X') + MasterHash('YY') + MasterHash('ZZZ')
            byte[] Salt11 = SaltedHash(masterSecret,
                                       Encoding.ASCII.GetBytes(ConstValue.NON_FIPS_MASTER_SECRET_X),
                                       clientRandom,
                                       serverRandom);
            byte[] Salt21 = SaltedHash(masterSecret,
                                       Encoding.ASCII.GetBytes(ConstValue.NON_FIPS_MASTER_SECRET_YY),
                                       clientRandom,
                                       serverRandom);
            byte[] Salt31 = SaltedHash(masterSecret,
                                       Encoding.ASCII.GetBytes(ConstValue.NON_FIPS_MASTER_SECRET_ZZZ),
                                       clientRandom,
                                       serverRandom);
            byte[] sessionKey = RdpbcgrUtility.ConcatenateArrays(Salt11, Salt21, Salt31);

            // MACKey128 = First128Bits(SessionKeyBlob)
            macKey = GetFirstNBits(128, sessionKey);

            // FinalHash(K) = MD5(K + ClientRandom + ServerRandom)
            // InitialClientDecryptKey128 = FinalHash(Second128Bits(SessionKeyBlob))
            byte[] tempKey = GetLastNBits(128, GetFirstNBits(128 * 2, sessionKey));
            clientDecKey = FinalHash(tempKey, clientRandom, serverRandom);

            // FinalHash(K) = MD5(K + ClientRandom + ServerRandom)
            // InitialClientEncryptKey128 = FinalHash(Third128Bits(SessionKeyBlob))
            tempKey      = GetLastNBits(128, GetFirstNBits(128 * 3, sessionKey));
            clientEncKey = FinalHash(tempKey, clientRandom, serverRandom);
        }
Ejemplo n.º 8
0
        private TS_LICENSE_PDU ConstructLicensePDU(bMsgType_Values messageType, LicensingMessage message)
        {
            TS_LICENSE_PDU pdu = new TS_LICENSE_PDU(rdpbcgrClient.context);

            RdpbcgrUtility.FillCommonHeader(rdpbcgrClient.context, ref pdu.commonHeader, TS_SECURITY_HEADER_flags_Values.SEC_LICENSE_PKT);
            pdu.LicensingMessage  = message;
            pdu.preamble.bMsgType = messageType;
            pdu.preamble.bVersion = bVersion_Values.PREAMBLE_VERSION_3_0 | bVersion_Values.EXTENDED_ERROR_MSG_SUPPORTED;
            return(pdu);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Construct and send CLIENT_LICENSE_INFO
        /// Meanwhile, generate the two licensing keys: licensing encryption key and MAC salt key.
        /// </summary>
        public void SendClientLicenseInformation(KeyExchangeAlg preferredKeyExchangeAlg, uint platformId, byte[] licenseInfo, CLIENT_HARDWARE_ID clientHardwareID)
        {
            CLIENT_LICENSE_INFO info = new CLIENT_LICENSE_INFO();

            info.PreferredKeyExchangeAlg = preferredKeyExchangeAlg;
            info.PlatformId = platformId;

            info.LicenseInfo.blobData  = licenseInfo;
            info.LicenseInfo.wBlobLen  = (ushort)licenseInfo.Length;
            info.LicenseInfo.wBlobType = wBlobType_Values.BB_DATA_BLOB;

            var random = new Random();

            clientRandom = new byte[32];
            random.NextBytes(clientRandom);
            info.ClientRandom = clientRandom;

            preMasterSecret = new byte[48];
            random.NextBytes(preMasterSecret);

            EncryptionAlgorithm.GenerateLicensingKeys(preMasterSecret, clientRandom, serverRandom, out macSaltKey, out licensingEncryptionKey);
            if (macSaltKey == null)
            {
                throw new Exception("The generated MAC-salt-key should not be NULL!");
            }

            if (licensingEncryptionKey == null)
            {
                throw new Exception("The generated LicensingEncryptionKey should not be NULL!");
            }

            info.EncryptedPreMasterSecret.blobData  = RdpbcgrUtility.GenerateEncryptedRandom(preMasterSecret, publicExponent, modulus);
            info.EncryptedPreMasterSecret.wBlobLen  = (ushort)info.EncryptedPreMasterSecret.blobData.Length;
            info.EncryptedPreMasterSecret.wBlobType = wBlobType_Values.BB_RANDOM_BLOB;

            CLIENT_HARDWARE_ID hardwareID = new CLIENT_HARDWARE_ID();

            hardwareID = clientHardwareID;

            info.EncryptedHWID.wBlobType = wBlobType_Values.BB_ENCRYPTED_DATA_BLOB;
            var hardwareIDBytes = TypeMarshal.ToBytes <CLIENT_HARDWARE_ID>(hardwareID);

            info.EncryptedHWID.blobData = RC4(hardwareIDBytes);
            info.EncryptedHWID.wBlobLen = (ushort)info.EncryptedHWID.blobData.Length;

            // MACData (16 bytes): An array of 16 bytes containing an MD5 digest (Message Authentication Code (MAC))
            // that is generated over the unencrypted Client Hardware Identification structure.
            info.MACData = EncryptionAlgorithm.GenerateNonFIPSDataSignature(macSaltKey, hardwareIDBytes, 16 * 8); // n is 16 * 8 bits.

            TS_LICENSE_PDU pdu = ConstructLicensePDU(bMsgType_Values.LICENSE_INFO, new LicensingMessage {
                ClientLicenseInfo = info
            });

            rdpbcgrClient.SendBytes(pdu.ToBytes());
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Construct and send CLIENT_NEW_LICENSE_REQUEST
        /// Meanwhile, generate the two licensing keys: licensing encryption key and MAC salt key.
        /// </summary>
        public void SendClientNewLicenseRequest(KeyExchangeAlg preferredKeyExchangeAlg, uint platformId, string clientUserName, string clientMachineName)
        {
            CLIENT_NEW_LICENSE_REQUEST request = new CLIENT_NEW_LICENSE_REQUEST();

            request.PreferredKeyExchangeAlg = preferredKeyExchangeAlg;
            request.PlatformId = platformId;

            var random = new Random();

            clientRandom = new byte[32];
            random.NextBytes(clientRandom);
            request.ClientRandom = clientRandom;

            preMasterSecret = new byte[48];
            random.NextBytes(preMasterSecret);

            // Generate licensingEncryptionKey and macSaltKey
            EncryptionAlgorithm.GenerateLicensingKeys(preMasterSecret, clientRandom, serverRandom, out macSaltKey, out licensingEncryptionKey);
            if (macSaltKey == null)
            {
                throw new Exception("The generated MAC-salt-key should not be NULL!");
            }

            if (licensingEncryptionKey == null)
            {
                throw new Exception("The generated LicensingEncryptionKey should not be NULL!");
            }

            try
            {
                request.EncryptedPreMasterSecret.blobData  = RdpbcgrUtility.GenerateEncryptedRandom(preMasterSecret, publicExponent, modulus);
                request.EncryptedPreMasterSecret.wBlobLen  = (ushort)request.EncryptedPreMasterSecret.blobData.Length;
                request.EncryptedPreMasterSecret.wBlobType = wBlobType_Values.BB_RANDOM_BLOB;

                request.ClientUserName.wBlobType = wBlobType_Values.BB_CLIENT_USER_NAME_BLOB;
                request.ClientUserName.blobData  = Encoding.UTF8.GetBytes(clientUserName);
                request.ClientUserName.wBlobLen  = (ushort)request.ClientUserName.blobData.Length;

                request.ClientMachineName.wBlobType = wBlobType_Values.BB_CLIENT_MACHINE_NAME_BLOB;
                request.ClientMachineName.blobData  = Encoding.UTF8.GetBytes(clientMachineName);
                request.ClientMachineName.wBlobLen  = (ushort)request.ClientMachineName.blobData.Length;

                TS_LICENSE_PDU pdu = ConstructLicensePDU(bMsgType_Values.NEW_LICENSE_REQUEST, new LicensingMessage {
                    ClientNewLicenseRequest = request
                });
                var bytes = pdu.ToBytes();
                rdpbcgrClient.SendBytes(bytes);
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        /// <summary>
        /// Update session key for Non-FIPS according to section 5.3.7 Session Key Updates.
        /// </summary>
        /// <param name="initialKey">The initial session key.</param>
        /// <param name="currentKey">The current session key.</param>
        /// <param name="encryptionMethod">The current encryption method.</param>
        /// <returns>The new session key.</returns>
        private static byte[] UpdateKey(byte[] initialKey, byte[] currentKey, EncryptionMethods encryptionMethod)
        {
            byte[] pad1   = ConstValue.NON_FIPS_PAD1;
            byte[] pad2   = ConstValue.NON_FIPS_PAD2;
            byte[] newKey = null;

            // SHAComponent = SHA(InitialEncryptKey + Pad1 + CurrentEncryptKey)
            byte[] shaComponentBuffer = RdpbcgrUtility.ConcatenateArrays(initialKey, pad1, currentKey);
            byte[] shaComponent       = ShaHash(shaComponentBuffer);

            // TempKey128 = MD5(InitialEncryptKey + Pad2 + SHAComponent)
            byte[] tempKey128Buffer = RdpbcgrUtility.ConcatenateArrays(initialKey, pad2, shaComponent);
            byte[] tempKey128       = MD5Hash(tempKey128Buffer);

            if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT)
            {
                // S-TableEncrypt = InitRC4(TempKey128)
                RC4CryptoServiceProvider rc4 = new RC4CryptoServiceProvider();
                ICryptoTransform         ict = rc4.CreateEncryptor(tempKey128, null);

                // NewEncryptKey128 = RC4(TempKey128, S-TableEncrypt)
                newKey = ict.TransformFinalBlock(tempKey128, 0, tempKey128.Length);
            }
            else if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT ||
                     encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT)
            {
                // TempKey64 = First64Bits(TempKey128)
                byte[] tempKey64 = GetFirstNBits(64, tempKey128);

                // S-TableEncrypt = InitRC4(TempKey64)
                RC4CryptoServiceProvider rc4 = new RC4CryptoServiceProvider();
                ICryptoTransform         ict = rc4.CreateEncryptor(tempKey64, null);

                // PreSaltKey = RC4(TempKey64, S-TableEncrypt)
                byte[] preSaltKey = ict.TransformFinalBlock(tempKey64, 0, tempKey64.Length);

                if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT)
                {
                    // NewEncryptKey40 = 0xD1269E + Last40Bits(PreSaltKey)
                    newKey = RdpbcgrUtility.ConcatenateArrays(ConstValue.NON_FIPS_SALT_40BIT, GetLastNBits(40, preSaltKey));
                }
                else
                {
                    // NewEncryptKey56 = 0xD1 + Last56Bits(PreSaltKey)
                    newKey = RdpbcgrUtility.ConcatenateArrays(ConstValue.NON_FIPS_SALT_56BIT, GetLastNBits(56, preSaltKey));
                }
            }
            // else do nothing

            return(newKey);
        }
        /// <summary>
        /// Generate the licensing encryption and MAC salt keys for RDPELE according to [MS-RDPELE] section 5.1.2
        /// </summary>
        /// <param name="preMasterSecret">The client random generated by client.</param>
        /// <param name="clientRandom">The client random generated by client.</param>
        /// <param name="serverRandom">The server random received from server.</param>
        /// <param name="macKey">The computed MACKey.</param>
        /// <param name="licensingEncryptionKey">The computed licensing encrypt key.</param>
        public static void GenerateLicensingKeys(byte[] preMasterSecret,
                                                 byte[] clientRandom,
                                                 byte[] serverRandom,
                                                 out byte[] macKey,
                                                 out byte[] licensingEncryptionKey)
        {
            // [MS-RDPELE] 5.1.2
            // SaltedHash(S, I) = MD5(S + SHA(I + S + ClientRandom + ServerRandom))
            // PreMasterHash(I) = SaltedHash(PremasterSecret, I)
            // MasterSecret = PreMasterHash('A') + PreMasterHash('BB') + PreMasterHash('CCC')
            byte[] Salt1 = SaltedHash(preMasterSecret,
                                      Encoding.ASCII.GetBytes(ConstValue.NON_FIPS_MASTER_SECRET_A),
                                      clientRandom,
                                      serverRandom);
            byte[] Salt2 = SaltedHash(preMasterSecret,
                                      Encoding.ASCII.GetBytes(ConstValue.NON_FIPS_MASTER_SECRET_BB),
                                      clientRandom,
                                      serverRandom);
            byte[] Salt3 = SaltedHash(preMasterSecret,
                                      Encoding.ASCII.GetBytes(ConstValue.NON_FIPS_MASTER_SECRET_CCC),
                                      clientRandom,
                                      serverRandom);
            byte[] masterSecret = RdpbcgrUtility.ConcatenateArrays(Salt1, Salt2, Salt3);

            //  SaltedHash2(S, I) = MD5(S + SHA-1 (I + S + ServerRandom + ClientRandom))
            //  MasterHash(I) = SaltedHash2(MasterSecret, I)
            //  SessionKeyBlob = MasterHash('A') + MasterHash('BB') + MasterHash('CCC')

            // SaltedHash2 is SaltedHash with swapped serverRandaom and clientRandom.
            byte[] Salt11 = SaltedHash(masterSecret,
                                       Encoding.ASCII.GetBytes(ConstValue.NON_FIPS_MASTER_SECRET_A),
                                       serverRandom,
                                       clientRandom);
            byte[] Salt21 = SaltedHash(masterSecret,
                                       Encoding.ASCII.GetBytes(ConstValue.NON_FIPS_MASTER_SECRET_BB),
                                       serverRandom,
                                       clientRandom);
            byte[] Salt31 = SaltedHash(masterSecret,
                                       Encoding.ASCII.GetBytes(ConstValue.NON_FIPS_MASTER_SECRET_CCC),
                                       serverRandom,
                                       clientRandom);
            byte[] sessionKey = RdpbcgrUtility.ConcatenateArrays(Salt11, Salt21, Salt31);

            //  MAC-salt-key = First128Bits(SessionKeyBlob)
            macKey = GetFirstNBits(128, sessionKey);

            // FinalHash(K) = MD5(K + ClientRandom + ServerRandom)
            // LicensingEncryptionKey = FinalHash(Second128Bits(SessionKeyBlob))
            byte[] tempKey = GetLastNBits(128, GetFirstNBits(128 * 2, sessionKey));
            licensingEncryptionKey = FinalHash(tempKey, clientRandom, serverRandom);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Send static virtual channel data
        /// </summary>
        /// <param name="channelId">Channel ID</param>
        /// <param name="channelPduHeader">Channel PDU Header</param>
        /// <param name="SVCData"></param>
        public void SendPacket(UInt16 channelId, CHANNEL_PDU_HEADER channelPduHeader, byte[] SVCData)
        {
            Virtual_Channel_RAW_Pdu channelPdu = new Virtual_Channel_RAW_Pdu(context);

            RdpbcgrUtility.FillCommonHeader(ref channelPdu.commonHeader,
                                            TS_SECURITY_HEADER_flags_Values.SEC_IGNORE_SEQNO
                                            | TS_SECURITY_HEADER_flags_Values.SEC_RESET_SEQNO,
                                            context,
                                            channelId);
            channelPdu.virtualChannelData = SVCData;
            channelPdu.channelPduHeader   = channelPduHeader;

            context.Client.SendPdu(channelPdu);
        }
Ejemplo n.º 14
0
        public override byte[] ToBytes()
        {
            byte[] licensingMessageBytes = null;
            switch (preamble.bMsgType)
            {
            case bMsgType_Values.None:
                break;

            case bMsgType_Values.LICENSE_REQUEST:
                licensingMessageBytes = TypeMarshal.ToBytes <SERVER_LICENSE_REQUEST>(LicensingMessage.ServerLicenseRequest.Value);
                break;

            case bMsgType_Values.PLATFORM_CHALLENGE:
                licensingMessageBytes = TypeMarshal.ToBytes <SERVER_PLATFORM_CHALLENGE>(LicensingMessage.ServerPlatformChallenge.Value);
                break;

            case bMsgType_Values.NEW_LICENSE:
                licensingMessageBytes = TypeMarshal.ToBytes <SERVER_NEW_LICENSE>(LicensingMessage.ServerNewLicense.Value);
                break;

            case bMsgType_Values.UPGRADE_LICENSE:
                licensingMessageBytes = TypeMarshal.ToBytes <SERVER_UPGRADE_LICENSE>(LicensingMessage.ServerUgradeLicense.Value);
                break;

            case bMsgType_Values.LICENSE_INFO:
                licensingMessageBytes = TypeMarshal.ToBytes <CLIENT_LICENSE_INFO>(LicensingMessage.ClientLicenseInfo.Value);
                break;

            case bMsgType_Values.NEW_LICENSE_REQUEST:
                licensingMessageBytes = TypeMarshal.ToBytes <CLIENT_NEW_LICENSE_REQUEST>(LicensingMessage.ClientNewLicenseRequest.Value);
                break;

            case bMsgType_Values.PLATFORM_CHALLENGE_RESPONSE:
                licensingMessageBytes = TypeMarshal.ToBytes <CLIENT_PLATFORM_CHALLENGE_RESPONSE>(LicensingMessage.ClientPlatformChallengeResponse.Value);
                break;

            case bMsgType_Values.ERROR_ALERT:
                licensingMessageBytes = TypeMarshal.ToBytes <LICENSE_ERROR_MESSAGE>(LicensingMessage.LicenseError.Value);
                break;

            default:
                break;
            }

            preamble.wMsgSize = (ushort)(licensingMessageBytes.Length + TypeMarshal.GetBlockMemorySize <LICENSE_PREAMBLE>(preamble));
            List <byte> totalBuffer = new List <byte>();

            RdpbcgrEncoder.EncodeSlowPathPdu(totalBuffer, commonHeader, TypeMarshal.ToBytes <LICENSE_PREAMBLE>(preamble).Concat(licensingMessageBytes).ToArray(), context);
            return(RdpbcgrUtility.ToBytes(totalBuffer.ToArray()));
        }
        /// <summary>
        /// Generate the Non-FIPS MAC signature for the given data.
        /// </summary>
        /// <param name="macKey">MAC key used for generating MAC signature.</param>
        /// <param name="data">The given Data</param>
        /// <returns>The MAC signature.</returns>
        private static byte[] GenerateNonFIPSDataSignature(byte[] macKey, byte[] data)
        {
            byte[] pad1 = ConstValue.NON_FIPS_PAD1;
            byte[] pad2 = ConstValue.NON_FIPS_PAD2;

            // SHAComponent = SHA(MACKeyN + Pad1 + DataLength + Data)
            byte[] temp    = RdpbcgrUtility.ConcatenateArrays(macKey, pad1, BitConverter.GetBytes(data.Length), data);
            byte[] shaData = ShaHash(temp);

            // MACSignature = First64Bits(MD5(MACKeyN + Pad2 + SHAComponent))
            byte[] md5Temp = RdpbcgrUtility.ConcatenateArrays(macKey, pad2, shaData);
            temp = MD5Hash(md5Temp);
            return(GetFirstNBits(64, temp));
        }
        /// <summary>
        /// Generate the session key for FIPS according to section 5.3.5 Initial Session Key Generation.
        /// </summary>
        /// <param name="clientRandom">The client random generated by client.</param>
        /// <param name="serverRandom">The server random received from server.</param>
        /// <param name="macKey">The computed MACKey.</param>
        /// <param name="clientEncKey">The computed client encrypt key.</param>
        /// <param name="clientDecKey">The computed client decrypt key.</param>
        private static void GenerateFIPSSessionKey(byte[] clientRandom,
                                                   byte[] serverRandom,
                                                   out byte[] macKey,
                                                   out byte[] clientEncKey,
                                                   out byte[] clientDecKey,
                                                   out byte[] serverEncKey,
                                                   out byte[] serverDecKey)
        {
            // ClientEncryptKeyT = SHA(Last128Bits(ClientRandom) + Last128Bits(ServerRandom))
            byte[] clientKeyT        = RdpbcgrUtility.ConcatenateArrays(GetLastNBits(128, clientRandom), GetLastNBits(128, serverRandom));
            byte[] clientEncryptKeyT = ShaHash(clientKeyT);

            // ClientDecryptKeyT = SHA(First128Bits(ClientRandom) + First128Bits(ServerRandom))
            clientKeyT = RdpbcgrUtility.ConcatenateArrays(GetFirstNBits(128, clientRandom), GetFirstNBits(128, serverRandom));
            byte[] clientDecryptKeyT = ShaHash(clientKeyT);

            // ClientEncryptKey = ClientEncryptKeyT + First8Bits(ClientEncryptKeyT)
            clientEncKey = RdpbcgrUtility.ConcatenateArrays(clientEncryptKeyT, GetFirstNBits(8, clientEncryptKeyT));
            serverDecKey = RdpbcgrUtility.ConcatenateArrays(clientEncryptKeyT, GetFirstNBits(8, clientEncryptKeyT));

            // ClientDecryptKey = ClientDecryptKeyT + First8Bits(ClientDecryptKeyT)
            clientDecKey = RdpbcgrUtility.ConcatenateArrays(clientDecryptKeyT, GetFirstNBits(8, clientDecryptKeyT));
            serverEncKey = RdpbcgrUtility.ConcatenateArrays(clientDecryptKeyT, GetFirstNBits(8, clientDecryptKeyT));

            ReverseEveryByte(clientEncKey);
            InsertZeroBit(ref clientEncKey);
            ReverseEveryByte(clientEncKey);
            FillOddParity(clientEncKey);

            ReverseEveryByte(clientDecKey);
            InsertZeroBit(ref clientDecKey);
            ReverseEveryByte(clientDecKey);
            FillOddParity(clientDecKey);

            ReverseEveryByte(serverEncKey);
            InsertZeroBit(ref serverEncKey);
            ReverseEveryByte(serverEncKey);
            FillOddParity(serverEncKey);

            ReverseEveryByte(serverDecKey);
            InsertZeroBit(ref serverDecKey);
            ReverseEveryByte(serverDecKey);
            FillOddParity(serverDecKey);

            byte[] temp = RdpbcgrUtility.ConcatenateArrays(clientDecryptKeyT, clientEncryptKeyT);
            macKey = ShaHash(temp);
        }
        /// <summary>
        /// Compute SaltedHash(S, I) = MD5(S + SHA(I + S + ClientRandom + ServerRandom))
        /// </summary>
        /// <param name="parameterS">Argument S in the formula above.</param>
        /// <param name="parameterI">Argument I in the formula above.</param>
        /// <param name="clientRandom">Argument ClientRandom in the formula above.</param>
        /// <param name="serverRandom">Argument ServerRandom in the formula above.</param>
        /// <returns>The computed result.</returns>
        private static byte[] SaltedHash(byte[] parameterS,
                                         byte[] parameterI,
                                         byte[] clientRandom,
                                         byte[] serverRandom)
        {
            // I + S + ClientRandom + ServerRandom
            byte[] shaData = RdpbcgrUtility.ConcatenateArrays(parameterI, parameterS, clientRandom, serverRandom);

            //Computing the ShaHash of (I + S + ClientRandom + ServerRandom)
            byte[] shaHash = ShaHash(shaData);

            // S + SHA(I + S + ClientRandom + ServerRandom)
            byte[] md5Data = RdpbcgrUtility.ConcatenateArrays(parameterS, shaHash);

            // Computing the MD5Hash of (S + SHA(I + S + ClientRandom + ServerRandom))
            return(MD5Hash(md5Data));
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Send a Tunnel Data PDU with RDP_BW_STOP in its subheader
        /// </summary>
        /// <param name="requestedProtocol"></param>
        /// <param name="sequenceNumber"></param>
        private void SendTunnelDataPdu_BWStop(Multitransport_Protocol_value requestedProtocol, ushort sequenceNumber)
        {
            AUTO_DETECT_REQUEST_TYPE requestType  = AUTO_DETECT_REQUEST_TYPE.RDP_BW_STOP_AFTER_CONNECTTIME_OR_RELIABLEUDP;
            RdpemtServer             rdpemtServer = rdpemtServerR;

            if (requestedProtocol == Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL)
            {
                requestType  = AUTO_DETECT_REQUEST_TYPE.RDP_BW_STOP_AFTER_CONNECTTIME_OR_LOSSYUDP;
                rdpemtServer = rdpemtServerL;
            }
            RDP_BW_STOP bwStop = RdpbcgrUtility.GenerateBandwidthMeasureStop(requestType, sequenceNumber);

            byte[]        reqData       = rdpbcgrServer.EncodeNetworkDetectionRequest(bwStop, true);
            List <byte[]> subHdDataList = new List <byte[]>();

            subHdDataList.Add(reqData);
            RDP_TUNNEL_DATA tunnelData = rdpemtServer.CreateTunnelDataPdu(null, subHdDataList);

            rdpemtServer.SendRdpemtPacket(tunnelData);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Send a Tunnel Data PDU with RTT Measure Request in its subheader
        /// </summary>
        /// <param name="udpTransportMode">Transport Mode: Reliable or Lossy</param>
        private void SendTunnelDataPdu_RTTMeasureRequest(Multitransport_Protocol_value requestedProtocol, ushort sequenceNumber)
        {
            AUTO_DETECT_REQUEST_TYPE requestType  = AUTO_DETECT_REQUEST_TYPE.RDP_RTT_REQUEST_AFTER_CONNECTTIME;
            RdpemtServer             rdpemtServer = rdpemtServerR;

            if (requestedProtocol == Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL)
            {
                rdpemtServer = rdpemtServerL;
            }
            RDP_RTT_REQUEST RTTRequest = RdpbcgrUtility.GenerateRTTMeasureRequest(requestType, sequenceNumber);

            byte[]        reqData       = rdpbcgrServer.EncodeNetworkDetectionRequest(RTTRequest, true);
            List <byte[]> subHdDataList = new List <byte[]>();

            subHdDataList.Add(reqData);
            RDP_TUNNEL_DATA tunnelData = rdpemtServer.CreateTunnelDataPdu(null, subHdDataList);

            rttDataStore.requestTime = DateTime.Now;
            rdpemtServer.SendRdpemtPacket(tunnelData);
        }
        private void CheckRDSTLSAuthenticationFields(RDSTLS_AuthenticationRequestPDUwithPasswordCredentials pdu)
        {
            // redirection GUID
            var  redirectionGuid      = RdpbcgrUtility.EncodeUnicodeStringToBytes(RdpbcgrTestData.Test_RedirectionGuid);
            bool checkRedirectionGuid = redirectionGuid.SequenceEqual(pdu.RedirectionGuid);

            this.TestSite.Assert.AreEqual <bool>(true, checkRedirectionGuid, "Redirection PDU should equal to that set in server redirection PDU.");

            // user name
            this.TestSite.Assert.AreEqual <string>(RdpbcgrTestData.Test_UserName, pdu.UserName, "User name should equal to that set in server redirection PDU.");

            // domain
            this.TestSite.Assert.AreEqual <string>(RdpbcgrTestData.Test_Domain, pdu.Domain, "Domain should equal to that set in server redirection PDU.");

            // password
            var  password      = RdpbcgrUtility.EncodeUnicodeStringToBytes(RdpbcgrTestData.Test_Password);
            bool checkPassword = password.SequenceEqual(pdu.Password);

            this.TestSite.Assert.AreEqual <bool>(true, checkPassword, "Password should equal to that set in server redirection PDU.");
        }
Ejemplo n.º 21
0
 /// <summary>
 /// Encode a structure to a byte list.
 /// </summary>
 /// <param name="buffer">The buffer list to contain the structure.
 /// This argument cannot be null. It may throw ArgumentNullException if it is null.</param>
 /// <param name="structure">The structure to be added to buffer list.
 /// This argument cannot be null. It may throw ArgumentNullException if it is null.</param>
 internal static void EncodeStructure(List <byte> buffer, object structure)
 {
     byte[] structBuffer = RdpbcgrUtility.StructToBytes(structure);
     buffer.AddRange(structBuffer);
 }
 /// <summary>
 /// Compute FinalHash(K) = MD5(K + ClientRandom + ServerRandom)
 /// </summary>
 /// <param name="parameterK">Argument K in the formula above.</param>
 /// <param name="clientRandom">Argument ClientRandom in the formula above.</param>
 /// <param name="serverRandom">Argument ServerRandom in the formula above.</param>
 /// <returns>The computed result.</returns>
 private static byte[] FinalHash(byte[] parameterK, byte[] clientRandom, byte[] serverRandom)
 {
     byte[] temp = RdpbcgrUtility.ConcatenateArrays(parameterK, clientRandom, serverRandom);
     return(MD5Hash(temp));
 }
        internal void GenerateSessionKey(byte[] clientRandom, byte[] serverRandom)
        {
            if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT ||
                encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT ||
                encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT)
            {
                byte[] mackey       = null;
                byte[] clientEncKey = null;
                byte[] clientDecKey = null;

                GenerateNonFIPSSessionKey(clientRandom, serverRandom, out mackey, out clientEncKey, out clientDecKey);
                if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT)
                {
                    // MACKey40 = 0xD1269E + Last40Bits(First64Bits(MACKey128))
                    byte[] salt  = ConstValue.NON_FIPS_SALT_40BIT;
                    byte[] first = GetFirstNBits(64, mackey);
                    byte[] last  = GetLastNBits(40, first);
                    macKey = RdpbcgrUtility.ConcatenateArrays(salt, last);

                    // InitialClientEncryptKey40 = 0xD1269E + Last40Bits(First64Bits(InitialClientEncryptKey128))
                    first = GetFirstNBits(64, clientEncKey);
                    last  = GetLastNBits(40, first);
                    currentClientEncryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last);
                    currentServerDecryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last);

                    // InitialClientDecryptKey40 = 0xD1269E + Last40Bits(First64Bits(InitialClientDecryptKey128))
                    first = GetFirstNBits(64, clientDecKey);
                    last  = GetLastNBits(40, first);
                    currentClientDecryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last);
                    currentServerEncryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last);
                }
                else if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT)
                {
                    // MACKey56 = 0xD1 + Last56Bits(First64Bits(MACKey128))
                    byte[] salt  = ConstValue.NON_FIPS_SALT_56BIT;
                    byte[] first = GetFirstNBits(64, mackey);
                    byte[] last  = GetLastNBits(56, first);
                    macKey = RdpbcgrUtility.ConcatenateArrays(salt, last);

                    // InitialClientEncryptKey56 = 0xD1 + Last56Bits(First64Bits(InitialClientEncryptKey128))
                    first = GetFirstNBits(64, clientEncKey);
                    last  = GetLastNBits(56, first);
                    currentClientEncryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last);
                    currentServerDecryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last);

                    // InitialClientDecryptKey56 = 0xD1 + Last56Bits(First64Bits(InitialClientDecryptKey128))
                    first = GetFirstNBits(64, clientDecKey);
                    last  = GetLastNBits(56, first);
                    currentClientDecryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last);
                    currentServerEncryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last);
                }
                else // encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT
                {
                    macKey = mackey;
                    currentClientEncryptKey = clientEncKey;
                    currentServerDecryptKey = clientEncKey;
                    currentClientDecryptKey = clientDecKey;
                    currentServerEncryptKey = clientDecKey;
                }

                initialClientDecryptKey = currentClientDecryptKey;
                initialClientEncryptKey = currentClientEncryptKey;
                initialServerEncryptKey = currentServerEncryptKey;
                initialServerDecryptKey = currentServerDecryptKey;
                RC4CryptoServiceProvider rc4Enc = new RC4CryptoServiceProvider();
                rc4Encrypt       = rc4Enc.CreateEncryptor(currentClientEncryptKey, null);
                rc4EncryptServer = rc4Enc.CreateEncryptor(currentServerEncryptKey, null);
                RC4CryptoServiceProvider rc4Dec = new RC4CryptoServiceProvider();
                rc4Decrypt       = rc4Dec.CreateDecryptor(currentClientDecryptKey, null);
                rc4DecryptServer = rc4Dec.CreateDecryptor(currentServerDecryptKey, null);
            }
            else if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_FIPS)
            {
                GenerateFIPSSessionKey(clientRandom, serverRandom, out macKey,
                                       out currentClientEncryptKey, out currentClientDecryptKey,
                                       out currentServerEncryptKey, out currentServerDecryptKey);
                initialClientDecryptKey = currentClientDecryptKey;
                initialClientEncryptKey = currentClientEncryptKey;
                initialServerDecryptKey = currentServerDecryptKey;
                initialServerEncryptKey = currentServerEncryptKey;

                // suppress "CA5353:TripleDESCannotBeUsed" message, since TripleDES is used according protocol definition in MS-RDPBCGR
                desEncrypt      = new TripleDESCryptoServiceProvider();
                desEncrypt.IV   = ConstValue.TRPLE_DES_IV;
                desEncrypt.Key  = currentClientEncryptKey;
                desEncrypt.Mode = CipherMode.CBC;

                desDecrypt      = new TripleDESCryptoServiceProvider();
                desDecrypt.IV   = ConstValue.TRPLE_DES_IV;
                desDecrypt.Key  = currentClientDecryptKey;
                desDecrypt.Mode = CipherMode.CBC;

                desEncryptServer      = new TripleDESCryptoServiceProvider();
                desEncryptServer.IV   = ConstValue.TRPLE_DES_IV;
                desEncryptServer.Key  = currentServerEncryptKey;
                desEncryptServer.Mode = CipherMode.CBC;

                desDecryptServer      = new TripleDESCryptoServiceProvider();
                desDecryptServer.IV   = ConstValue.TRPLE_DES_IV;
                desDecryptServer.Key  = currentServerDecryptKey;
                desDecryptServer.Mode = CipherMode.CBC;
            }
            else  // the encryption method is ENCRYPTION_METHOD_NONE or error
            {
                macKey = null;
                initialClientEncryptKey = null;
                initialClientDecryptKey = null;
                currentClientEncryptKey = null;
                currentClientDecryptKey = null;
                initialServerEncryptKey = null;
                initialServerDecryptKey = null;
                currentServerEncryptKey = null;
                currentServerDecryptKey = null;
                rc4Encrypt       = null;
                rc4Decrypt       = null;
                rc4EncryptServer = null;
                rc4DecryptServer = null;
                desEncrypt       = null;
                desDecrypt       = null;
                desEncryptServer = null;
                desDecryptServer = null;
            }

            // the cumulative encryption/decryption count
            // indicating how many encryptions/decryptions have been carried out.
            encryptionCount = 0;  // the first encryption start with 0
            decryptionCount = -1; // after the first decryption, decryptionCount++ up to 0
        }