private static TLObject ParseMessageContainer(BinaryReader reader) { try { var RawObject = new JArray(); var MessageCount = IntegerUtil.Deserialize(reader); for (int i = 0; i < MessageCount; i++) { RawObject.Add(new JObject { ["msg_id"] = LongUtil.Deserialize(reader), ["seqno"] = IntegerUtil.Deserialize(reader), ["bytes"] = IntegerUtil.Deserialize(reader), ["body"] = TLObject.Deserialize(reader) }); } return(new TLObject(JObject.FromObject(new { _ = "msg_container", messages = RawObject }))); } catch { return(null); } }
internal RemoteInfo(IntPtr ptr) { if (ptr != IntPtr.Zero) { var ri = (FsRemoteInfo)Marshal.PtrToStructure(ptr, typeof(FsRemoteInfo)); IsDirectory = (ri.SizeHigh == -1 && ri.SizeLow == 0); if (!IsDirectory) { Size = LongUtil.MakeLong(ri.SizeHigh, ri.SizeLow); } LastWriteTime = DateTimeUtil.FromFileTime(ri.LastWriteTime); Attributes = (FileAttributes)ri.Attributes; } }
internal void CopyTo(IntPtr ptr) { if (ptr != IntPtr.Zero) { var data = new ArchiveHeaderStruct { ArchiveName = ArchiveName, FileName = FileName, FileAttr = (int)FileAttributes, FileCRC = FileCRC, FileTime = DateTimeUtil.ToArchiveHeaderTime(FileTime), PackSizeHigh = (uint)LongUtil.High(PackedSize), PackSizeLow = (uint)LongUtil.Low(PackedSize), UnpSizeHigh = (uint)LongUtil.High(UnpackedSize), UnpSizeLow = (uint)LongUtil.Low(UnpackedSize), }; Marshal.StructureToPtr(data, ptr, false); } }
internal void CopyTo(IntPtr pFindData) { if (pFindData != IntPtr.Zero) { var findData = new FsFindData() { FileName = FileName, AlternateFileName = AlternateFileName, FileAttributes = (int)Attributes, FileSizeHigh = LongUtil.High(FileSize), FileSizeLow = LongUtil.Low(FileSize), CreationTime = DateTimeUtil.ToFileTime(CreationTime), LastAccessTime = DateTimeUtil.ToFileTime(LastAccessTime), LastWriteTime = DateTimeUtil.ToFileTime(LastWriteTime), Reserved0 = Reserved0, Reserved1 = Reserved1, }; Marshal.StructureToPtr(findData, pFindData, false); } }
/// <summary> /// Inverse of <see cref="EncryptMessageData"/> for incoming server messages. /// </summary> public TLObject DecryptMessageData(byte[] body, bool client = false) { if (body.Length < 8) { throw new Exception("Cannot decrypt a message of 8 bytes."); } using (var memory = new MemoryStream(body)) using (var reader = new BinaryReader(memory)) using (var sha = new SHA256Managed()) { var serverKeyID = reader.ReadUInt64(); if (serverKeyID != AuthInfo.AuthKey.KeyID) { throw new Exception($"Server replied with an invalid auth key: {serverKeyID}"); } var MessageKey = reader.ReadBytes(16); (var AES_Key, var AES_ID) = CalcKey(AuthInfo.AuthKey.Key, MessageKey, client); body = AES.DecryptIGE(reader.ReadBytes(body.Length - 24), AES_Key, AES_ID); // https://core.telegram.org/mtproto/security_guidelines // Sections "checking sha256 hash" and "message length" var SHAHash = sha.ComputeHash(AuthInfo.AuthKey.Key .Skip(client ? 88 : 96).Take(32) .Concat(body) .ToArray()); var SHASlice = SHAHash.Skip(8).Take(16); if (!SHASlice.SequenceEqual(MessageKey)) { throw new Exception("The message key could not be validated."); } } TLObject obj = null; byte[] RawObject = null; var remote_msg_id = -1L; var remote_sequence = -1L; using (var memory = new MemoryStream(body)) using (var reader = new BinaryReader(memory)) { // The salt could be 0 if we are starting anew and haven't received one yet if (Salt != LongUtil.Deserialize(reader) && Salt != 0) { throw new Exception("The salt could not be validated"); } if (ID != LongUtil.Deserialize(reader)) { throw new Exception("The session ID could not be validated"); } remote_msg_id = LongUtil.Deserialize(reader); // ToDo: Check sequence_number remote_sequence = IntegerUtil.Deserialize(reader); RawObject = reader.ReadBytes(IntegerUtil.Deserialize(reader)); obj = TLObject.Deserialize(RawObject); } return(new TLObject(JToken.FromObject(new { _ = "Message", msg_id = remote_msg_id, seqno = remote_sequence, bytes = RawObject, body = JToken.Parse(obj.ToString()) }))); }