public async Task <TRecv> ExecuteMethodAsync <TSend, TRecv>(TLMethod <TSend, TRecv> method) where TSend : TLObject, new() where TRecv : TLObject, new() { await SendObjectAsync(method.SendObject).ConfigureAwait(false); int headerLen = _tcpClient.GetStream().ReadByte(); if (headerLen == 0x7F) { headerLen = _tcpClient.GetStream().ReadByte(); headerLen += _tcpClient.GetStream().ReadByte() << 8; headerLen += _tcpClient.GetStream().ReadByte() << 16; } headerLen *= 4; Console.WriteLine("....receiving...."); byte[] recvArr = new byte[headerLen]; await _tcpClient.GetStream().ReadAsync(recvArr, 0, headerLen).ConfigureAwait(false); DebugUtils.DumpBytes(recvArr); Console.WriteLine("\n....done...."); method.ReceiveObject = TLRootSerializer.Deserialize <TRecv>(recvArr.ToList()); return(method.ReceiveObject); }
public override object Deserialize(List <byte> byteList, TLPropertyAttribute attribute) { UInt32 value = (UInt32)TLRootSerializer.Deserialize(byteList, typeof(UInt32)); if (value == BoolTrue) { return(true); } if (value == BoolFalse) { return(false); } throw new ArgumentException("Unrecognized bool sequence."); }
public override object Deserialize(List <byte> byteList, TLPropertyAttribute attribute) { UInt32 expectedClassId = GetSerializerType().GetClassId(); UInt32 classId = (UInt32)TLRootSerializer.Deserialize(byteList, typeof(UInt32)); if (expectedClassId != classId) { throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "{0} =/= {1}", expectedClassId, classId)); } dynamic vector = Activator.CreateInstance(typeof(TLVector <>).MakeGenericType(attribute.VectorType)); int len = (int)TLRootSerializer.Deserialize(byteList, typeof(Int32)); for (int i = 0; i < len; i++) { vector.Content.Add((dynamic)TLRootSerializer.Deserialize(byteList, attribute.VectorType)); } return(vector); }
private async Task DoAuthenticationAsync(IConnectionInfo connectionInfo) { Random r = new Random(); IPlainConnection connection = new PlainConnection(connectionInfo); await connection.ConnectAsync().ConfigureAwait(false); TLReqPqMethod method = new TLReqPqMethod(); ReqPq reqPq = new ReqPq { Nonce = new byte[16] }; r.NextBytes(reqPq.Nonce); TLFrame <ReqPq> frame = new TLFrame <ReqPq> { AuthKey = 0, MessageId = DateTime.Now.ToUnixTime() * (Int64)Math.Pow(2, 32), MessageLength = 20, Content = reqPq }; method.SendObject = frame; TLFrame <ResPq> resPqFrame = await connection.ExecuteMethodAsync(method).ConfigureAwait(false); UInt64 pq = (UInt64)TLRootSerializer.Deserialize(resPqFrame.Content.Pq.Content.Reverse().ToList(), typeof(UInt64)); PqData pqData = _pqSolver.SolvePq(pq); PqInnerData innerData = new PqInnerData { Nonce = resPqFrame.Content.Nonce, ServerNonce = resPqFrame.Content.ServerNonce, NewNonce = new byte[32], Pq = resPqFrame.Content.Pq, P = new TLBytes(TLRootSerializer.Serialize(pqData.P).Reverse().ToArray()), Q = new TLBytes(TLRootSerializer.Serialize(pqData.Q).Reverse().ToArray()) }; r.NextBytes(innerData.NewNonce); byte[] data = TLRootSerializer.Serialize(innerData); UInt64 fingerprint = resPqFrame.Content.Vector.Content.First(); SHA1 shaAlgo = SHA1.Create(); byte[] sha1 = shaAlgo.ComputeHash(data); List <byte> dataWithHash = sha1.Concat(data).ToList(); while (dataWithHash.Count < 255) { dataWithHash.Add((byte)(r.Next() & 0xFF)); } byte[] encData = _rsaCrypter.EncryptBytes(dataWithHash.ToArray(), fingerprint); TLFrame <ReqDhParams> reqDhFrame = new TLFrame <ReqDhParams> { AuthKey = 0, MessageId = DateTime.Now.ToUnixTime() * (Int64)Math.Pow(2, 32), MessageLength = 320, Content = new ReqDhParams { Nonce = innerData.Nonce, ServerNonce = innerData.ServerNonce, P = innerData.P, Q = innerData.Q, Fingerprint = TLRootSerializer.Serialize(fingerprint), EncryptedData = new TLBytes(encData) } }; TLReqDhParamsMethod reqDhMethod = new TLReqDhParamsMethod { SendObject = reqDhFrame }; TLFrame <ServerDhParams> dhParamsFrame = await connection.ExecuteMethodAsync(reqDhMethod).ConfigureAwait(false); ServerDhParamsOk paramsOk = dhParamsFrame.Content as ServerDhParamsOk; if (paramsOk == null) { throw new ServerException("Didn't receive ServerDhParamsOk(0xd0e8075c)"); } // SHA1(new_nonce + server_nonce) byte[] tmpAesKey = shaAlgo.ComputeHash(ArrayUtils.Concat(innerData.NewNonce, innerData.ServerNonce)); // + substr (SHA1(server_nonce + new_nonce), 0, 12) tmpAesKey = tmpAesKey.Concat(shaAlgo.ComputeHash(ArrayUtils.Concat(innerData.ServerNonce, innerData.NewNonce)).Take(12).ToArray()).ToArray(); // substr (SHA1(server_nonce + new_nonce), 12, 8) byte[] tmpAesIv = shaAlgo.ComputeHash(ArrayUtils.Concat(innerData.ServerNonce, innerData.NewNonce)).Skip(12).Take(8).ToArray(); // + SHA1(new_nonce + new_nonce) tmpAesIv = tmpAesIv.Concat(shaAlgo.ComputeHash(ArrayUtils.Concat(innerData.NewNonce, innerData.NewNonce))).ToArray(); // + substr (new_nonce, 0, 4); tmpAesIv = tmpAesIv.Concat(innerData.NewNonce.Take(4)).ToArray(); byte[] decData = _aes256IgeCrypter.DecryptBytes(paramsOk.EncryptedAnswer.Content, tmpAesKey, tmpAesIv); byte[] hash = decData.Take(20).ToArray(); decData = decData.Skip(20).ToArray(); ServerDhInnerData dhInnerData = TLRootSerializer.Deserialize <ServerDhInnerData>(decData.ToList()); if (!ArrayUtils.Equal(hash, shaAlgo.ComputeHash(TLRootSerializer.Serialize(dhInnerData)))) { throw new SecurityException("SHA-1 hash not equal to ServerDhInnerData"); } }
public override object Deserialize(List <byte> byteList, TLPropertyAttribute attribute) { TLBytes bytes = (TLBytes)TLRootSerializer.Deserialize(byteList, typeof(TLBytes)); return(Encoding.UTF8.GetString(bytes.Content)); }