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;
}