/// <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()); }
/// <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; } }