/// <summary> /// Encode GCC Conference Create Request according to [T124]. /// </summary> /// <param name="gccPdu">The data to be encoded.</param> /// <returns>The encoded data.</returns> private static byte[] EncodeGccRspData(ConnectGCCRsp gccPdu) { if (gccPdu == null) { return null; } #region Encode userData List<byte> userData = new List<byte>(); #region Encode serverCoreData structure TS_UD_CS_CORE if (gccPdu.serverCoreData != null) { List<byte> coreData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.serverCoreData.header); RdpbcgrEncoder.EncodeStructure(coreData, (uint)gccPdu.serverCoreData.version); RdpbcgrEncoder.EncodeStructure(coreData, (uint)gccPdu.serverCoreData.clientRequestedProtocols); //earlyCapabilityFlags is optional. if(gccPdu.serverCoreData.earlyCapabilityFlags != 0) RdpbcgrEncoder.EncodeStructure(coreData, (uint)gccPdu.serverCoreData.earlyCapabilityFlags); userData.AddRange(coreData.ToArray()); } #endregion Encode serverCoreData structure TS_UD_CS_CORE #region Encode serverNetworkData TS_UD_CS_NET if (gccPdu.serverNetworkData != null) { List<byte> networkData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(networkData, gccPdu.serverNetworkData.header); RdpbcgrEncoder.EncodeStructure(networkData, gccPdu.serverNetworkData.MCSChannelId); RdpbcgrEncoder.EncodeStructure(networkData, gccPdu.serverNetworkData.channelCount); for (int i = 0; i < gccPdu.serverNetworkData.channelCount; ++i) { RdpbcgrEncoder.EncodeStructure(networkData, gccPdu.serverNetworkData.channelIdArray[i]); } if (gccPdu.serverNetworkData.Pad != null) { RdpbcgrEncoder.EncodeBytes(networkData, gccPdu.serverNetworkData.Pad); } userData.AddRange(networkData.ToArray()); } #endregion Encode serverNetworkData TS_UD_CS_NET #region Encode serverSecurityData TS_UD_CS_SEC if (gccPdu.serverSecurityData != null) { List<byte> securityData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(securityData, gccPdu.serverSecurityData.header); RdpbcgrEncoder.EncodeStructure(securityData, (uint)gccPdu.serverSecurityData.encryptionMethod); RdpbcgrEncoder.EncodeStructure(securityData, (uint)gccPdu.serverSecurityData.encryptionLevel); if (gccPdu.serverSecurityData.encryptionMethod != EncryptionMethods.ENCRYPTION_METHOD_NONE || gccPdu.serverSecurityData.encryptionLevel != EncryptionLevel.ENCRYPTION_LEVEL_NONE) { RdpbcgrEncoder.EncodeStructure(securityData, gccPdu.serverSecurityData.serverRandomLen.actualData); RdpbcgrEncoder.EncodeStructure(securityData, gccPdu.serverSecurityData.serverCertLen.actualData); if (gccPdu.serverSecurityData.serverRandom != null) { RdpbcgrEncoder.EncodeBytes(securityData, gccPdu.serverSecurityData.serverRandom); } #region Encode certificate if (gccPdu.serverSecurityData.serverCertificate != null) { RdpbcgrEncoder.EncodeStructure(securityData, (uint)gccPdu.serverSecurityData.serverCertificate.dwVersion); if (gccPdu.serverSecurityData.serverCertificate.dwVersion == SERVER_CERTIFICATE_dwVersion_Values.CERT_CHAIN_VERSION_1) { PROPRIETARYSERVERCERTIFICATE cert = (PROPRIETARYSERVERCERTIFICATE)gccPdu.serverSecurityData.serverCertificate.certData; RdpbcgrEncoder.EncodeStructure(securityData, (uint)cert.dwSigAlgId); RdpbcgrEncoder.EncodeStructure(securityData, (uint)cert.dwKeyAlgId); RdpbcgrEncoder.EncodeStructure(securityData, (ushort)cert.wPublicKeyBlobType); RdpbcgrEncoder.EncodeStructure(securityData, cert.wPublicKeyBlobLen); RdpbcgrEncoder.EncodeStructure(securityData, (uint)cert.PublicKeyBlob.magic); RdpbcgrEncoder.EncodeStructure(securityData, cert.PublicKeyBlob.keylen); RdpbcgrEncoder.EncodeStructure(securityData, cert.PublicKeyBlob.bitlen); RdpbcgrEncoder.EncodeStructure(securityData, cert.PublicKeyBlob.datalen); RdpbcgrEncoder.EncodeStructure(securityData, cert.PublicKeyBlob.pubExp); RdpbcgrEncoder.EncodeBytes(securityData, cert.PublicKeyBlob.modulus); RdpbcgrEncoder.EncodeStructure(securityData, (ushort)cert.wSignatureBlobType); RdpbcgrEncoder.EncodeStructure(securityData, cert.wSignatureBlobLen); RdpbcgrEncoder.EncodeBytes(securityData, cert.SignatureBlob); } else if (gccPdu.serverSecurityData.serverCertificate.dwVersion == SERVER_CERTIFICATE_dwVersion_Values.CERT_CHAIN_VERSION_2) { X509_CERTIFICATE_CHAIN cert = (X509_CERTIFICATE_CHAIN)gccPdu.serverSecurityData.serverCertificate.certData; RdpbcgrEncoder.EncodeStructure(securityData, (uint)cert.NumCertBlobs); for (int i = 0; i < cert.CertBlobArray.Length; i++) { RdpbcgrEncoder.EncodeStructure(securityData, cert.CertBlobArray[i].cbCert); RdpbcgrEncoder.EncodeBytes(securityData, cert.CertBlobArray[i].abCert); } RdpbcgrEncoder.EncodeBytes(securityData, cert.Padding); } } #endregion } userData.AddRange(securityData.ToArray()); } #endregion Encode serverSecurityData TS_UD_CS_SEC #region Encode serverMessageChannelData TS_UD_SC_MCS_MSGCHANNEL if (gccPdu.serverMessageChannelData != null) { List<byte> msgChannelData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(msgChannelData, gccPdu.serverMessageChannelData.header); RdpbcgrEncoder.EncodeStructure(msgChannelData, gccPdu.serverMessageChannelData.MCSChannelID); userData.AddRange(msgChannelData.ToArray()); } #endregion #region Encode serverMultitransportChannelData TS_UD_SC_MULTITRANSPORT if (gccPdu.serverMultitransportChannelData != null) { List<byte> multiTranChannelData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(multiTranChannelData, gccPdu.serverMultitransportChannelData.header); RdpbcgrEncoder.EncodeStructure(multiTranChannelData, (uint)gccPdu.serverMultitransportChannelData.flags); userData.AddRange(multiTranChannelData.ToArray()); } #endregion #endregion Encode userData #region Filling GCC Conference Create Request ConferenceCreateResponse gccCCrsp = new ConferenceCreateResponse(); gccCCrsp.nodeID = new UserID(gccPdu.nodeID); gccCCrsp.tag = new Asn1Integer(gccPdu.tag); gccCCrsp.result = new ConferenceCreateResponse_result(gccPdu.ccrResult); //gccCCrsp.extElem1 = new Asn1OpenExt(); UserDataElement[] dataElements = new UserDataElement[1]; dataElements[0] = new UserDataElement(); dataElements[0].key = new Key(Key.h221NonStandard, new H221NonStandardIdentifier(gccPdu.H221Key)); dataElements[0].value = new Asn1OctetString(userData.ToArray()); gccCCrsp.userData = new UserData(dataElements); ConnectGCCPDU cGccPdu = new ConnectGCCPDU(ConnectGCCPDU.conferenceCreateResponse, gccCCrsp); #endregion Filling GCC Conference Create Request #region Encode ConnectData Asn1PerEncodingBuffer perBuffer = new Asn1PerEncodingBuffer(true); cGccPdu.PerEncode(perBuffer); byte[] asnEncodedData = perBuffer.ByteArrayData; Key key = new Key(Key.obj, new Asn1ObjectIdentifier(ConstValue.MCS_ATTRIBUTE_ID)); ConnectData connectData = new ConnectData(key, new Asn1OctetString(asnEncodedData)); Asn1PerEncodingBuffer perBuffer2 = new Asn1PerEncodingBuffer(true); connectData.PerEncode(perBuffer2); #endregion Encode ConnectData #region Workaround for Windows encoding issue //reset the ConnectPDULength to one-byte length: 0x2A byte[] returnButter = null; if ((perBuffer2.ByteArrayData[7] & 0x80) == 0x80) { //If length is two-byte, delete one byte returnButter = new byte[perBuffer2.ByteArrayData.Length - 1]; Array.Copy(perBuffer2.ByteArrayData, returnButter, 7); Array.Copy(perBuffer2.ByteArrayData, 8, returnButter, 7, returnButter.Length - 7); } else { returnButter = new byte[perBuffer2.ByteArrayData.Length]; Array.Copy(perBuffer2.ByteArrayData, returnButter, perBuffer2.ByteArrayData.Length); } returnButter[7] = 0x2A; #endregion return returnButter; }
public MCSConnectResponse() { gccPdu = new ConnectGCCRsp(); }