mirror of
https://github.com/wiz0u/WTelegramClient.git
synced 2025-12-06 06:52:01 +01:00
Encryption class public + TL Methods/Helpers
This commit is contained in:
parent
48d005b605
commit
2e95576be5
|
|
@ -83,7 +83,7 @@ public class MTProtoGenerator : IIncrementalGenerator
|
|||
ns = symbol.ContainingNamespace.ToString();
|
||||
name = symbol.Name;
|
||||
if (!namespaces.TryGetValue(ns, out var classes)) namespaces[ns] = classes = [];
|
||||
if (name is "_Message" or "RpcResult" or "MsgCopy")
|
||||
if (name is "_Message" or "MsgCopy")
|
||||
{
|
||||
classes[name] = "\t\tpublic void WriteTL(BinaryWriter writer) => throw new NotSupportedException();";
|
||||
continue;
|
||||
|
|
@ -93,7 +93,7 @@ public class MTProtoGenerator : IIncrementalGenerator
|
|||
else if (name != "Null")
|
||||
{
|
||||
if (ns == "TL.Methods")
|
||||
methodsTL.AppendLine($"\t\t\t[0x{id:X8}] = {(ns == "TL" ? "" : ns + '.')}{name}{(symbol.IsGenericType ? "<IObject>" : "")}.ReadTL,");
|
||||
methodsTL.AppendLine($"\t\t\t[0x{id:X8}] = {(ns == "TL" ? "" : ns + '.')}{name}{(symbol.IsGenericType ? "<object>" : "")}.ReadTL,");
|
||||
if (ns != "TL.Methods" || name == "Ping")
|
||||
tableTL.AppendLine($"\t\t\t[0x{id:X8}] = {(ns == "TL" ? "" : ns + '.')}{name}.ReadTL,");
|
||||
}
|
||||
|
|
@ -176,7 +176,7 @@ public class MTProtoGenerator : IIncrementalGenerator
|
|||
writeTl.AppendLine($"writer.WriteTLMessages({member.Name});");
|
||||
break;
|
||||
case "TL.IObject": case "TL.IMethod<X>":
|
||||
readTL.AppendLine($"r.{member.Name} = {(memberType == "TL.IObject" ? "" : $"({memberType})")}reader.ReadTLObject();");
|
||||
readTL.AppendLine($"r.{member.Name} = {(memberType == "TL.IObject" ? "reader.ReadTLObject()" : "reader.ReadTLMethod<X>()")};");
|
||||
writeTl.AppendLine($"{member.Name}.WriteTL(writer);");
|
||||
break;
|
||||
case "System.Collections.Generic.Dictionary<long, TL.User>":
|
||||
|
|
@ -187,15 +187,24 @@ public class MTProtoGenerator : IIncrementalGenerator
|
|||
readTL.AppendLine($"r.{member.Name} = reader.ReadTLDictionary<ChatBase>();");
|
||||
writeTl.AppendLine($"writer.WriteTLVector({member.Name}.Values.ToArray());");
|
||||
break;
|
||||
case "object":
|
||||
readTL.AppendLine($"r.{member.Name} = reader.ReadTLObject();");
|
||||
writeTl.AppendLine($"writer.WriteTLValue({member.Name}, {member.Name}.GetType());");
|
||||
break;
|
||||
default:
|
||||
if (member.Type is IArrayTypeSymbol arrayType)
|
||||
{
|
||||
if (name is "FutureSalts")
|
||||
{
|
||||
readTL.AppendLine($"r.{member.Name} = reader.ReadTLRawVector<{memberType.Substring(0, memberType.Length - 2)}>(0x0949D9DC).ToArray();");
|
||||
writeTl.AppendLine($"writer.WriteTLRawVector({member.Name}, 16);");
|
||||
}
|
||||
else
|
||||
{
|
||||
readTL.AppendLine($"r.{member.Name} = reader.ReadTLVector<{memberType.Substring(0, memberType.Length - 2)}>();");
|
||||
writeTl.AppendLine($"writer.WriteTLVector({member.Name});");
|
||||
}
|
||||
}
|
||||
else if (member.Type.BaseType.SpecialType == SpecialType.System_Enum)
|
||||
{
|
||||
readTL.AppendLine($"r.{member.Name} = ({memberType})reader.ReadUInt32();");
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ namespace WTelegram
|
|||
if (serverDHparams is not ServerDHParamsOk serverDHparamsOk) throw new WTException("not server_DH_params_ok");
|
||||
if (serverDHparamsOk.nonce != nonce) throw new WTException("Nonce mismatch");
|
||||
if (serverDHparamsOk.server_nonce != resPQ.server_nonce) throw new WTException("Server Nonce mismatch");
|
||||
var (tmp_aes_key, tmp_aes_iv) = ConstructTmpAESKeyIV(resPQ.server_nonce, pqInnerData.new_nonce);
|
||||
var (tmp_aes_key, tmp_aes_iv) = ConstructTmpAESKeyIV(sha1, resPQ.server_nonce, pqInnerData.new_nonce);
|
||||
var answer = AES_IGE_EncryptDecrypt(serverDHparamsOk.encrypted_answer, tmp_aes_key, tmp_aes_iv, false);
|
||||
|
||||
using var answerReader = new BinaryReader(new MemoryStream(answer));
|
||||
|
|
@ -163,8 +163,9 @@ namespace WTelegram
|
|||
session.AuthKey = authKey;
|
||||
session.Salt = BinaryPrimitives.ReadInt64LittleEndian(pqInnerData.new_nonce.raw) ^ BinaryPrimitives.ReadInt64LittleEndian(resPQ.server_nonce.raw);
|
||||
session.OldSalt = session.Salt;
|
||||
}
|
||||
|
||||
(byte[] key, byte[] iv) ConstructTmpAESKeyIV(TL.Int128 server_nonce, Int256 new_nonce)
|
||||
public static (byte[] key, byte[] iv) ConstructTmpAESKeyIV(SHA1 sha1, TL.Int128 server_nonce, Int256 new_nonce)
|
||||
{
|
||||
byte[] tmp_aes_key = new byte[32], tmp_aes_iv = new byte[32];
|
||||
sha1.TransformBlock(new_nonce, 0, 32, null, 0);
|
||||
|
|
@ -183,7 +184,6 @@ namespace WTelegram
|
|||
sha1.Initialize();
|
||||
return (tmp_aes_key, tmp_aes_iv);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void CheckGoodPrime(BigInteger p, int g)
|
||||
{
|
||||
|
|
@ -278,7 +278,7 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB
|
|||
-----END RSA PUBLIC KEY-----");
|
||||
}
|
||||
|
||||
internal static byte[] EncryptDecryptMessage(Span<byte> input, bool encrypt, int x, byte[] authKey, byte[] msgKey, int msgKeyOffset, SHA256 sha256)
|
||||
public static byte[] EncryptDecryptMessage(Span<byte> input, bool encrypt, int x, byte[] authKey, byte[] msgKey, int msgKeyOffset, SHA256 sha256)
|
||||
{
|
||||
// first, construct AES key & IV
|
||||
byte[] aes_key = new byte[32], aes_iv = new byte[32];
|
||||
|
|
@ -299,7 +299,7 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB
|
|||
return AES_IGE_EncryptDecrypt(input, aes_key, aes_iv, encrypt);
|
||||
}
|
||||
|
||||
internal static byte[] AES_IGE_EncryptDecrypt(Span<byte> input, byte[] aes_key, byte[] aes_iv, bool encrypt)
|
||||
public static byte[] AES_IGE_EncryptDecrypt(Span<byte> input, byte[] aes_key, byte[] aes_iv, bool encrypt)
|
||||
{
|
||||
if (input.Length % 16 != 0) throw new WTException("AES_IGE input size not divisible by 16");
|
||||
|
||||
|
|
|
|||
40
src/TL.cs
40
src/TL.cs
|
|
@ -16,7 +16,7 @@ namespace TL
|
|||
#else
|
||||
public interface IObject { }
|
||||
#endif
|
||||
public interface IMethod<ReturnType> : IObject { }
|
||||
public interface IMethod<out ReturnType> : IObject { }
|
||||
public interface IPeerResolver { IPeerInfo UserOrChat(Peer peer); }
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
|
|
@ -105,6 +105,17 @@ namespace TL
|
|||
#endif
|
||||
}
|
||||
|
||||
public static IMethod<X> ReadTLMethod<X>(this BinaryReader reader)
|
||||
{
|
||||
uint ctorNb = reader.ReadUInt32();
|
||||
if (!Layer.Methods.TryGetValue(ctorNb, out var ctor))
|
||||
throw new WTelegram.WTException($"Cannot find method for ctor #{ctorNb:x}");
|
||||
var method = ctor?.Invoke(reader);
|
||||
if (method is IMethod<bool> && typeof(X) == typeof(object))
|
||||
method = new BoolMethod { query = method };
|
||||
return (IMethod<X>)method;
|
||||
}
|
||||
|
||||
internal static void WriteTLValue(this BinaryWriter writer, object value, Type valueType)
|
||||
{
|
||||
if (value == null)
|
||||
|
|
@ -222,6 +233,21 @@ namespace TL
|
|||
writer.WriteTLValue(array.GetValue(i), elementType);
|
||||
}
|
||||
|
||||
internal static void WriteTLRawVector(this BinaryWriter writer, Array array, int elementSize)
|
||||
{
|
||||
var startPos = writer.BaseStream.Position;
|
||||
int count = array.Length;
|
||||
var elementType = array.GetType().GetElementType();
|
||||
for (int i = count - 1; i >= 0; i--)
|
||||
{
|
||||
writer.BaseStream.Position = startPos + i * elementSize;
|
||||
writer.WriteTLValue(array.GetValue(i), elementType);
|
||||
}
|
||||
writer.BaseStream.Position = startPos;
|
||||
writer.Write(count);
|
||||
writer.BaseStream.Position = startPos + count * elementSize + 4;
|
||||
}
|
||||
|
||||
internal static List<T> ReadTLRawVector<T>(this BinaryReader reader, uint ctorNb)
|
||||
{
|
||||
int count = reader.ReadInt32();
|
||||
|
|
@ -443,4 +469,16 @@ namespace TL
|
|||
|
||||
[TLDef(0x3072CFA1)] //gzip_packed#3072cfa1 packed_data:bytes = Object
|
||||
public sealed partial class GzipPacked : IObject { public byte[] packed_data; }
|
||||
|
||||
public sealed class Null<X> : IObject
|
||||
{
|
||||
public readonly static Null<X> Instance = new();
|
||||
public void WriteTL(BinaryWriter writer) => writer.WriteTLNull(typeof(X));
|
||||
}
|
||||
|
||||
public sealed class BoolMethod : IMethod<object>
|
||||
{
|
||||
public IObject query;
|
||||
public void WriteTL(BinaryWriter writer) => query.WriteTL(writer);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue