diff --git a/README.md b/README.md index d048c31..8ac107a 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,6 @@ It's a perfect fit for any developer who would like to send data directly to Tel # Table of contents - [How do I add this to my project?](#how-do-i-add-this-to-my-project) -- [Dependencies](#dependencies) - [Starter Guide](#starter-guide) - [Quick configuration](#quick-configuration) - [First requests](#first-requests) @@ -41,11 +40,6 @@ or build from source 1. Compile source with VS2015 or MonoDevelop 1. Add reference to ```TLSharp.Core.dll``` to your awesome project. -# Dependencies - -TLSharp has a few dependenices, most of functionality implemented from scratch. -All dependencies listed in [package.conf file](https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/packages.config). - # Starter Guide ## Quick Configuration diff --git a/TLSharp.Core/MTProto/Crypto/Crc32.cs b/TLSharp.Core/MTProto/Crypto/Crc32.cs index c22f851..ce62fe9 100644 --- a/TLSharp.Core/MTProto/Crypto/Crc32.cs +++ b/TLSharp.Core/MTProto/Crypto/Crc32.cs @@ -4,32 +4,42 @@ using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; -using Ionic.Crc; namespace TLSharp.Core.MTProto.Crypto { - public class Crc32 : HashAlgorithm + /// + /// Implements a 32-bit CRC hash algorithm compatible with Zip etc. + /// + /// + /// Crc32 should only be used for backward compatibility with older file formats + /// and algorithms. It is not secure enough for new applications. + /// If you need to call multiple times for the same data either use the HashAlgorithm + /// interface or remember that the result of one Compute call needs to be ~ (XOR) before + /// being passed in as the seed for the next Compute call. + /// + public sealed class Crc32 : HashAlgorithm { public const UInt32 DefaultPolynomial = 0xedb88320u; public const UInt32 DefaultSeed = 0xffffffffu; - private UInt32 hash; - private UInt32 seed; - private UInt32[] table; - private static UInt32[] defaultTable; + static UInt32[] defaultTable; + + readonly UInt32 seed; + readonly UInt32[] table; + UInt32 hash; public Crc32() + : this(DefaultPolynomial, DefaultSeed) { - table = InitializeTable(DefaultPolynomial); - seed = DefaultSeed; - hash = seed; } public Crc32(UInt32 polynomial, UInt32 seed) { + if (!BitConverter.IsLittleEndian) + throw new PlatformNotSupportedException("Not supported on Big Endian processors"); + table = InitializeTable(polynomial); - this.seed = seed; - hash = seed; + this.seed = hash = seed; } public override void Initialize() @@ -37,35 +47,28 @@ namespace TLSharp.Core.MTProto.Crypto hash = seed; } - protected override void HashCore(byte[] buffer, int start, int length) + protected override void HashCore(byte[] array, int ibStart, int cbSize) { - hash = CalculateHash(table, hash, buffer, start, length); + hash = CalculateHash(table, hash, array, ibStart, cbSize); } - /// - /// Возвращает хеш в BigEndian - /// - /// protected override byte[] HashFinal() { - byte[] hashBuffer = UInt32ToBigEndianBytes(~hash); - this.HashValue = hashBuffer; + var hashBuffer = UInt32ToBigEndianBytes(~hash); + HashValue = hashBuffer; return hashBuffer; } - public override int HashSize - { - get { return 32; } - } + public override int HashSize { get { return 32; } } public static UInt32 Compute(byte[] buffer) { - return ~CalculateHash(InitializeTable(DefaultPolynomial), DefaultSeed, buffer, 0, buffer.Length); + return Compute(DefaultSeed, buffer); } public static UInt32 Compute(UInt32 seed, byte[] buffer) { - return ~CalculateHash(InitializeTable(DefaultPolynomial), seed, buffer, 0, buffer.Length); + return Compute(DefaultPolynomial, seed, buffer); } public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer) @@ -73,20 +76,20 @@ namespace TLSharp.Core.MTProto.Crypto return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length); } - private static UInt32[] InitializeTable(UInt32 polynomial) + static UInt32[] InitializeTable(UInt32 polynomial) { if (polynomial == DefaultPolynomial && defaultTable != null) return defaultTable; - UInt32[] createTable = new UInt32[256]; - for (int i = 0; i < 256; i++) + var createTable = new UInt32[256]; + for (var i = 0; i < 256; i++) { - UInt32 entry = (UInt32)i; - for (int j = 0; j < 8; j++) + var entry = (UInt32)i; + for (var j = 0; j < 8; j++) if ((entry & 1) == 1) entry = (entry >> 1) ^ polynomial; else - entry = entry >> 1; + entry >>= 1; createTable[i] = entry; } @@ -96,25 +99,23 @@ namespace TLSharp.Core.MTProto.Crypto return createTable; } - private static UInt32 CalculateHash(UInt32[] table, UInt32 seed, byte[] buffer, int start, int size) + static UInt32 CalculateHash(UInt32[] table, UInt32 seed, IList buffer, int start, int size) { - UInt32 crc = seed; - for (int i = start; i < size; i++) - unchecked - { - crc = (crc >> 8) ^ table[buffer[i] ^ crc & 0xff]; - } - return crc; + var hash = seed; + for (var i = start; i < start + size; i++) + hash = (hash >> 8) ^ table[buffer[i] ^ hash & 0xff]; + return hash; } - private byte[] UInt32ToBigEndianBytes(UInt32 x) + static byte[] UInt32ToBigEndianBytes(UInt32 uint32) { - return new byte[] { - (byte)((x >> 24) & 0xff), - (byte)((x >> 16) & 0xff), - (byte)((x >> 8) & 0xff), - (byte)(x & 0xff) - }; + var result = BitConverter.GetBytes(uint32); + + if (BitConverter.IsLittleEndian) + Array.Reverse(result); + + return result; } } + } diff --git a/TLSharp.Core/Network/MtProtoSender.cs b/TLSharp.Core/Network/MtProtoSender.cs index cccab37..91e4457 100644 --- a/TLSharp.Core/Network/MtProtoSender.cs +++ b/TLSharp.Core/Network/MtProtoSender.cs @@ -2,11 +2,11 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.IO.Compression; using System.Linq; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; -using Ionic.Zlib; using TeleSharp.TL; using TLSharp.Core.Exceptions; using TLSharp.Core.MTProto; @@ -251,11 +251,20 @@ namespace TLSharp.Core.Network token.ThrowIfCancellationRequested(); uint code = messageReader.ReadUInt32(); - byte[] packedData = GZipStream.UncompressBuffer(Serializers.Bytes.Read(messageReader)); - using (MemoryStream packedStream = new MemoryStream(packedData, false)) - using (BinaryReader compressedReader = new BinaryReader(packedStream)) + + byte[] packedData = Serializers.Bytes.Read(messageReader); + using (var ms = new MemoryStream()) { - processMessage(messageId, sequence, compressedReader, request, token); + using (var packedStream = new MemoryStream(packedData, false)) + using (var zipStream = new GZipStream(packedStream, CompressionMode.Decompress)) + { + zipStream.CopyTo(ms); + ms.Position = 0; + } + using (BinaryReader compressedReader = new BinaryReader(ms)) + { + processMessage(messageId, sequence, compressedReader, request, token); + } } return true; @@ -337,27 +346,20 @@ namespace TLSharp.Core.Network } else if (innerCode == 0x3072cfa1) { - try + // gzip_packed + byte[] packedData = Serializers.Bytes.Read(messageReader); + using (var ms = new MemoryStream()) { - // gzip_packed - byte[] packedData = Serializers.Bytes.Read(messageReader); - using (var ms = new MemoryStream()) + using (var packedStream = new MemoryStream(packedData, false)) + using (var zipStream = new GZipStream(packedStream, CompressionMode.Decompress)) { - using (var packedStream = new MemoryStream(packedData, false)) - using (var zipStream = new GZipStream(packedStream, CompressionMode.Decompress)) - { - zipStream.CopyTo(ms); - ms.Position = 0; - } - using (var compressedReader = new BinaryReader(ms)) - { - request.DeserializeResponse(compressedReader); - } + zipStream.CopyTo(ms); + ms.Position = 0; + } + using (var compressedReader = new BinaryReader(ms)) + { + request.DeserializeResponse(compressedReader); } - } - catch (ZlibException ex) - { - } } else diff --git a/TLSharp.Core/Network/TcpMessage.cs b/TLSharp.Core/Network/TcpMessage.cs index 91ef84c..2a0f9b4 100644 --- a/TLSharp.Core/Network/TcpMessage.cs +++ b/TLSharp.Core/Network/TcpMessage.cs @@ -1,6 +1,7 @@ using System; using System.IO; -using Ionic.Crc; +using System.Linq; +using TLSharp.Core.MTProto.Crypto; namespace TLSharp.Core.Network { @@ -35,9 +36,9 @@ namespace TLSharp.Core.Network binaryWriter.Write(Body.Length + 12); binaryWriter.Write(SequneceNumber); binaryWriter.Write(Body); - var crc32 = new CRC32(); - crc32.SlurpBlock(memoryStream.GetBuffer(), 0, 8 + Body.Length); - binaryWriter.Write(crc32.Crc32Result); + var crc32 = new Crc32(); + var checksum = crc32.ComputeHash(memoryStream.GetBuffer(), 0, 8 + Body.Length).Reverse().ToArray(); + binaryWriter.Write(checksum); var transportPacket = memoryStream.ToArray(); @@ -67,13 +68,12 @@ namespace TLSharp.Core.Network var seq = binaryReader.ReadInt32(); byte[] packet = binaryReader.ReadBytes(packetLength - 12); - var checksum = (int)binaryReader.ReadInt32(); + var checksum = binaryReader.ReadBytes(4); - var crc32 = new CRC32(); - crc32.SlurpBlock(body, 0, packetLength - 4); - var validChecksum = crc32.Crc32Result; + var crc32 = new Crc32(); + var computedChecksum = crc32.ComputeHash(body, 0, packetLength - 4).Reverse(); - if (checksum != validChecksum) + if (!checksum.SequenceEqual(computedChecksum)) { throw new InvalidOperationException("invalid checksum! skip"); } diff --git a/TLSharp.Core/Network/TcpTransport.cs b/TLSharp.Core/Network/TcpTransport.cs index 3750a76..d60d881 100644 --- a/TLSharp.Core/Network/TcpTransport.cs +++ b/TLSharp.Core/Network/TcpTransport.cs @@ -1,8 +1,10 @@ using System; +using System.Linq; using System.Net; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; +using TLSharp.Core.MTProto.Crypto; namespace TLSharp.Core.Network { @@ -73,18 +75,16 @@ namespace TLSharp.Core.Network var crcBytes = new byte[4]; if (await stream.ReadAsync(crcBytes, 0, 4, token).ConfigureAwait(false) != 4) throw new InvalidOperationException("Couldn't read the crc"); - int checksum = BitConverter.ToInt32(crcBytes, 0); byte[] rv = new byte[packetLengthBytes.Length + seqBytes.Length + body.Length]; Buffer.BlockCopy(packetLengthBytes, 0, rv, 0, packetLengthBytes.Length); Buffer.BlockCopy(seqBytes, 0, rv, packetLengthBytes.Length, seqBytes.Length); Buffer.BlockCopy(body, 0, rv, packetLengthBytes.Length + seqBytes.Length, body.Length); - var crc32 = new Ionic.Crc.CRC32(); - crc32.SlurpBlock(rv, 0, rv.Length); - var validChecksum = crc32.Crc32Result; + var crc32 = new Crc32(); + var computedChecksum = crc32.ComputeHash(rv).Reverse(); - if (checksum != validChecksum) + if (!crcBytes.SequenceEqual(computedChecksum)) { throw new InvalidOperationException("invalid checksum! skip"); } diff --git a/TLSharp.Core/TLSharp.Core.csproj b/TLSharp.Core/TLSharp.Core.csproj index 440dc55..4dff090 100644 --- a/TLSharp.Core/TLSharp.Core.csproj +++ b/TLSharp.Core/TLSharp.Core.csproj @@ -31,10 +31,6 @@ 4 - - ..\packages\MarkerMetro.Unity.Ionic.Zlib.2.0.0.14\lib\net35\Ionic.ZLib.dll - True - diff --git a/TLSharp.Core/TLSharp.Core.nuspec b/TLSharp.Core/TLSharp.Core.nuspec index 78b9628..c2c5747 100644 --- a/TLSharp.Core/TLSharp.Core.nuspec +++ b/TLSharp.Core/TLSharp.Core.nuspec @@ -20,8 +20,6 @@ It's a perfect fit for any developer who would like to send data directly to Tel Copyright 2016 - - \ No newline at end of file diff --git a/TLSharp.Core/packages.config b/TLSharp.Core/packages.config index 4966d6d..6b8deb9 100644 --- a/TLSharp.Core/packages.config +++ b/TLSharp.Core/packages.config @@ -1,5 +1,3 @@  - - \ No newline at end of file diff --git a/TeleSharp.TL/TLUtils.cs b/TeleSharp.TL/TLUtils.cs index 878ff08..1f8c80c 100644 --- a/TeleSharp.TL/TLUtils.cs +++ b/TeleSharp.TL/TLUtils.cs @@ -1,5 +1,4 @@ -using BigMath; -using BigMath.Utils; + using System; using System.Collections.Generic; using System.IO; @@ -159,26 +158,4 @@ namespace TeleSharp.TL writer.Write(src); } } - public class Int128Util - { - public static Int128 Deserialize(BinaryReader reader) - { - return reader.ReadBytes(16).ToInt128(0, true); - } - public static void Serialize(Int128 src, BinaryWriter writer) - { - writer.Write(src.ToBytes(true)); - } - } - public class Int256Util - { - public static Int256 Deserialize(BinaryReader reader) - { - return reader.ReadBytes(32).ToInt256(0, true); - } - public static void Serialize(Int256 src, BinaryWriter writer) - { - writer.Write(src.ToBytes(true)); - } - } } diff --git a/TeleSharp.TL/TeleSharp.TL.csproj b/TeleSharp.TL/TeleSharp.TL.csproj index 86a2cd7..b7120c1 100644 --- a/TeleSharp.TL/TeleSharp.TL.csproj +++ b/TeleSharp.TL/TeleSharp.TL.csproj @@ -31,10 +31,6 @@ 4 - - ..\packages\BigMath.0.5.0\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\BigMath.dll - True - diff --git a/TeleSharp.TL/packages.config b/TeleSharp.TL/packages.config index cde6ccb..6b8deb9 100644 --- a/TeleSharp.TL/packages.config +++ b/TeleSharp.TL/packages.config @@ -1,4 +1,3 @@  - \ No newline at end of file