private Tuple <byte[], ulong, int> DecodeMessage(byte[] body) { byte[] message; ulong remoteMessageId; int remoteSequence; using (var inputStream = new MemoryStream(body)) using (var inputReader = new BinaryReader(inputStream)) { if (inputReader.BaseStream.Length < 8) { throw new InvalidOperationException($"Can't decode packet"); } ulong remoteAuthKeyId = inputReader.ReadUInt64(); // TODO: check auth key id byte[] msgKey = inputReader.ReadBytes(16); // TODO: check msg_key correctness AESKeyData keyData = Helpers.CalcKey(_session.AuthKey.Data, msgKey, false); byte[] plaintext = AES.DecryptAES(keyData, inputReader.ReadBytes((int)(inputStream.Length - inputStream.Position))); logger.Debug(Sniffer.MessageIn(plaintext)); using (MemoryStream plaintextStream = new MemoryStream(plaintext)) using (BinaryReader plaintextReader = new BinaryReader(plaintextStream)) { var remoteSalt = plaintextReader.ReadUInt64(); var remoteSessionId = plaintextReader.ReadUInt64(); remoteMessageId = plaintextReader.ReadUInt64(); remoteSequence = plaintextReader.ReadInt32(); int msgLen = plaintextReader.ReadInt32(); message = plaintextReader.ReadBytes(msgLen); } } return(new Tuple <byte[], ulong, int>(message, remoteMessageId, remoteSequence)); }
public async Task Send(byte[] packet, TeleSharp.TL.TLMethod request) { request.MessageId = _session.GetNewMessageId(); byte[] msgKey; byte[] ciphertext; using (MemoryStream plaintextPacket = makeMemory(8 + 8 + 8 + 4 + 4 + packet.Length)) { using (BinaryWriter plaintextWriter = new BinaryWriter(plaintextPacket)) { plaintextWriter.Write(_session.Salt); plaintextWriter.Write(_session.Id); plaintextWriter.Write(request.MessageId); plaintextWriter.Write(GenerateSequence(request.Confirmed)); plaintextWriter.Write(packet.Length); plaintextWriter.Write(packet); var buffer = plaintextPacket.GetBuffer(); logger.Debug("Send {0} {1:x8} {2}", request, request.Constructor, Sniffer.MessageOut(buffer)); msgKey = Helpers.CalcMsgKey(buffer); ciphertext = AES.EncryptAES(Helpers.CalcKey(_session.AuthKey.Data, msgKey, true), plaintextPacket.GetBuffer()); } } using (MemoryStream ciphertextPacket = makeMemory(8 + 16 + ciphertext.Length)) { using (BinaryWriter writer = new BinaryWriter(ciphertextPacket)) { writer.Write(_session.AuthKey.Id); writer.Write(msgKey); writer.Write(ciphertext); await _transport.Send(ciphertextPacket.GetBuffer()); } } }