private StackPacket ExpectPdu(TimeSpan timeout) { return(rdpbcgrClient.ExpectPdu(timeout)); }
/// <summary> /// Expect the specified pdu from RDP server within the timeout. /// </summary> public TS_LICENSE_PDU ExpectPdu(TimeSpan timeout) { TS_LICENSE_PDU licensePdu = null; StackPacket packet = rdpbcgrClient.ExpectPdu(timeout); if (packet == null) { return(null); } if (packet is Server_License_Error_Pdu_Valid_Client) { licensePdu = new TS_LICENSE_PDU(rdpbcgrClient.context); licensePdu.commonHeader = ((Server_License_Error_Pdu_Valid_Client)packet).commonHeader; licensePdu.preamble = ((Server_License_Error_Pdu_Valid_Client)packet).preamble; licensePdu.LicensingMessage.LicenseError = ((Server_License_Error_Pdu_Valid_Client)packet).validClientMessage; } else if (packet is RdpelePdu) { licensePdu = new TS_LICENSE_PDU(rdpbcgrClient.context); licensePdu.commonHeader = ((RdpelePdu)packet).commonHeader; licensePdu.preamble = ((RdpelePdu)packet).preamble; licensePdu.FromBytes(((RdpelePdu)packet).rdpeleData); if (licensePdu.preamble.bMsgType == bMsgType_Values.LICENSE_REQUEST) { // Save server random and decode cert to get public key for future use. serverRandom = licensePdu.LicensingMessage.ServerLicenseRequest.Value.ServerRandom; // According to [MS-RDPELE] section 2.2.2.1 // The terminal server can choose not to send the certificate by setting the wblobLen field in the Licensing Binary BLOB structure to 0. // If encryption is in effect and is already protecting RDP traffic, the licensing protocol MAY<3> choose not to send the server certificate // (for RDP security measures, see [MS-RDPBCGR] sections 5.3 and 5.4). If the licensing protocol chooses not to send the server certificate, // then the client uses the public key obtained from the server certificate sent as part of Server Security Data in the // Server MCS Connect Response PDU (see [MS-RDPBCGR] section 2.2.1.4). if (licensePdu.LicensingMessage.ServerLicenseRequest.Value.ServerCertificate.wBlobLen == 0) { publicExponent = rdpbcgrClient.context.ServerExponent; modulus = rdpbcgrClient.context.ServerModulus; } else { int index = 0; SERVER_CERTIFICATE cert = RdpbcgrDecoder.DecodeServerCertificate( licensePdu.LicensingMessage.ServerLicenseRequest.Value.ServerCertificate.blobData, ref index, (uint)licensePdu.LicensingMessage.ServerLicenseRequest.Value.ServerCertificate.blobData.Length); RdpbcgrDecoder.DecodePubicKey(cert, out publicExponent, out modulus); } } else if (licensePdu.preamble.bMsgType == bMsgType_Values.PLATFORM_CHALLENGE) { // Decrypt platform challenge for future use. byte[] encryptedPlatformChallenge = licensePdu.LicensingMessage.ServerPlatformChallenge.Value.EncryptedPlatformChallenge.blobData; platformChallenge = RC4(encryptedPlatformChallenge); if (platformChallenge == null) { throw new Exception("The decrpyted PlatformChallenge should not be NULL!"); } if (!VerifyServerMAC(licensePdu.LicensingMessage.ServerPlatformChallenge.Value.MACData, platformChallenge)) { throw new Exception("The MACData of PLATFORM_CHALLENGE from Server is invalid!"); } } else if (licensePdu.preamble.bMsgType == bMsgType_Values.NEW_LICENSE) { // Decrypt the license info for future use. var decryptedLicenseInfo = RC4(licensePdu.LicensingMessage.ServerNewLicense.Value.EncryptedLicenseInfo.blobData); newLicenseInfo = TypeMarshal.ToStruct <NEW_LICENSE_INFO>(decryptedLicenseInfo); if (!VerifyServerMAC(licensePdu.LicensingMessage.ServerNewLicense.Value.MACData, decryptedLicenseInfo)) { throw new Exception("The MACData of SERVER_NEW_LICENSE from Server is invalid!"); } } else if (licensePdu.preamble.bMsgType == bMsgType_Values.UPGRADE_LICENSE) { // Decrypt the license info for future use. var decryptedLicenseInfo = RC4(licensePdu.LicensingMessage.ServerUgradeLicense.Value.EncryptedLicenseInfo.blobData); upgradedLicenseInfo = TypeMarshal.ToStruct <NEW_LICENSE_INFO>(decryptedLicenseInfo); if (!VerifyServerMAC(licensePdu.LicensingMessage.ServerUgradeLicense.Value.MACData, decryptedLicenseInfo)) { throw new Exception("The MACData of SERVER_UPGRADE_LICENSE from Server is invalid!"); } } else { throw new Exception($"The received PDU type should not be {licensePdu.preamble.bMsgType}!"); } } return(licensePdu); }