From bdbf17aa0745c4f72530d9a9048b6feba920ae33 Mon Sep 17 00:00:00 2001 From: Wizou <11647984+wiz0u@users.noreply.github.com> Date: Sat, 19 Feb 2022 03:30:50 +0100 Subject: [PATCH] Remove dependencies on Microsoft.Bcl.HashCode & System.Formats.Asn1 --- src/Compat.cs | 11 +++--- src/TL.cs | 80 +++++++++++++++++++------------------- src/WTelegramClient.csproj | 2 - 3 files changed, 45 insertions(+), 48 deletions(-) diff --git a/src/Compat.cs b/src/Compat.cs index 6aa4d0a..6ac6344 100644 --- a/src/Compat.cs +++ b/src/Compat.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; -using System.Formats.Asn1; +using System.Linq; using System.Net; using System.Numerics; using System.Security.Cryptography; @@ -61,17 +61,16 @@ namespace WTelegram return new IPEndPoint(IPAddress.Parse(addr[0..colon]), int.Parse(addr[(colon + 1)..])); } + private static readonly byte[] PemStart = new byte[] { 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01 }; internal static void ImportFromPem(this RSA rsa, string pem) { var header = pem.IndexOf("-----BEGIN RSA PUBLIC KEY-----"); var footer = pem.IndexOf("-----END RSA PUBLIC KEY-----"); if (header == -1 || footer <= header) throw new ArgumentException("Invalid RSA Public Key"); byte[] bytes = System.Convert.FromBase64String(pem[(header+30)..footer]); - var reader = new AsnReader(bytes, AsnEncodingRules.BER); - reader = reader.ReadSequence(Asn1Tag.Sequence); - var m = reader.ReadIntegerBytes(); - var e = reader.ReadIntegerBytes(); - rsa.ImportParameters(new RSAParameters { Modulus = m.ToArray(), Exponent = e.ToArray() }); + if (bytes.Length != 270 || !bytes.Take(8).SequenceEqual(PemStart) || bytes[265] != 0x02 || bytes[266] != 0x03) + throw new ArgumentException("Unrecognized sequence in RSA Public Key"); + rsa.ImportParameters(new RSAParameters { Modulus = bytes[8..265], Exponent = bytes[267..270] }); } } } diff --git a/src/TL.cs b/src/TL.cs index 1653543..9a91890 100644 --- a/src/TL.cs +++ b/src/TL.cs @@ -13,6 +13,39 @@ namespace TL public interface IMethod : IObject { } public interface IPeerResolver { IPeerInfo UserOrChat(Peer peer); } + [AttributeUsage(AttributeTargets.Class)] + public class TLDefAttribute : Attribute + { + public readonly uint CtorNb; + public TLDefAttribute(uint ctorNb) => CtorNb = ctorNb; + public bool inheritBefore; + } + + [AttributeUsage(AttributeTargets.Field)] + public class IfFlagAttribute : Attribute + { + public readonly int Bit; + public IfFlagAttribute(int bit) => Bit = bit; + } + + public class RpcException : Exception + { + public readonly int Code; + public RpcException(int code, string message) : base(message) => Code = code; + public override string ToString() { var str = base.ToString(); return str.Insert(str.IndexOf(':') + 1, " " + Code); } + } + + public class ReactorError : IObject + { + public Exception Exception; + } + + internal class BinaryReader : System.IO.BinaryReader + { + public readonly WTelegram.Client Client; + public BinaryReader(Stream stream, WTelegram.Client client) : base(stream) => Client = client; + } + internal static class Serialization { internal static void WriteTLObject(this BinaryWriter writer, T obj) where T : IObject @@ -72,13 +105,13 @@ namespace TL switch (Type.GetTypeCode(type)) { case TypeCode.Int32: writer.Write((int)value); break; - case TypeCode.UInt32: writer.Write((uint)value); break; case TypeCode.Int64: writer.Write((long)value); break; + case TypeCode.UInt32: writer.Write((uint)value); break; case TypeCode.UInt64: writer.Write((ulong)value); break; case TypeCode.Double: writer.Write((double)value); break; case TypeCode.String: writer.WriteTLString((string)value); break; - case TypeCode.DateTime: writer.WriteTLStamp((DateTime)value); break; case TypeCode.Boolean: writer.Write((bool)value ? 0x997275B5 : 0xBC799737); break; + case TypeCode.DateTime: writer.WriteTLStamp((DateTime)value); break; case TypeCode.Object: if (type.IsArray) if (value is byte[] bytes) @@ -109,8 +142,8 @@ namespace TL switch (Type.GetTypeCode(type)) { case TypeCode.Int32: return reader.ReadInt32(); - case TypeCode.UInt32: return reader.ReadUInt32(); case TypeCode.Int64: return reader.ReadInt64(); + case TypeCode.UInt32: return reader.ReadUInt32(); case TypeCode.UInt64: return reader.ReadUInt64(); case TypeCode.Double: return reader.ReadDouble(); case TypeCode.String: return reader.ReadTLString(); @@ -293,37 +326,16 @@ namespace TL #endif } - public class BinaryReader : System.IO.BinaryReader - { - public readonly WTelegram.Client Client; - public BinaryReader(Stream stream, WTelegram.Client client) : base(stream) => Client = client; - } - - [AttributeUsage(AttributeTargets.Class)] - public class TLDefAttribute : Attribute - { - public readonly uint CtorNb; - public TLDefAttribute(uint ctorNb) => CtorNb = ctorNb; - public bool inheritBefore; - } - - [AttributeUsage(AttributeTargets.Field)] - public class IfFlagAttribute : Attribute - { - public readonly int Bit; - public IfFlagAttribute(int bit) => Bit = bit; - } - public struct Int128 { public byte[] raw; - public Int128(BinaryReader reader) => raw = reader.ReadBytes(16); + public Int128(System.IO.BinaryReader reader) => raw = reader.ReadBytes(16); public Int128(RNGCryptoServiceProvider rng) => rng.GetBytes(raw = new byte[16]); public static bool operator ==(Int128 left, Int128 right) { for (int i = 0; i < 16; i++) if (left.raw[i] != right.raw[i]) return false; return true; } public static bool operator !=(Int128 left, Int128 right) { for (int i = 0; i < 16; i++) if (left.raw[i] != right.raw[i]) return true; return false; } public override bool Equals(object obj) => obj is Int128 other && this == other; - public override int GetHashCode() => HashCode.Combine(raw[0], raw[1]); + public override int GetHashCode() => BitConverter.ToInt32(raw, 0); public override string ToString() => Convert.ToHexString(raw); public static implicit operator byte[](Int128 int128) => int128.raw; } @@ -332,28 +344,16 @@ namespace TL { public byte[] raw; - public Int256(BinaryReader reader) => raw = reader.ReadBytes(32); + public Int256(System.IO.BinaryReader reader) => raw = reader.ReadBytes(32); public Int256(RNGCryptoServiceProvider rng) => rng.GetBytes(raw = new byte[32]); public static bool operator ==(Int256 left, Int256 right) { for (int i = 0; i < 32; i++) if (left.raw[i] != right.raw[i]) return false; return true; } public static bool operator !=(Int256 left, Int256 right) { for (int i = 0; i < 32; i++) if (left.raw[i] != right.raw[i]) return true; return false; } public override bool Equals(object obj) => obj is Int256 other && this == other; - public override int GetHashCode() => HashCode.Combine(raw[0], raw[1]); + public override int GetHashCode() => BitConverter.ToInt32(raw, 0); public override string ToString() => Convert.ToHexString(raw); public static implicit operator byte[](Int256 int256) => int256.raw; } - public class RpcException : Exception - { - public readonly int Code; - public RpcException(int code, string message) : base(message) => Code = code; - public override string ToString() { var str = base.ToString(); return str.Insert(str.IndexOf(':') + 1, " " + Code); } - } - - public class ReactorError : IObject - { - public Exception Exception; - } - // Below TL types are commented "parsed manually" from https://github.com/telegramdesktop/tdesktop/blob/dev/Telegram/Resources/tl/mtproto.tl [TLDef(0x7A19CB76)] //RSA_public_key#7a19cb76 n:bytes e:bytes = RSAPublicKey diff --git a/src/WTelegramClient.csproj b/src/WTelegramClient.csproj index 99206ed..493252f 100644 --- a/src/WTelegramClient.csproj +++ b/src/WTelegramClient.csproj @@ -47,8 +47,6 @@ - -