コード例 #1
0
ファイル: MtProtoSender.cs プロジェクト: DrEhsan/TeleTurk
        public async Task Send(MTProtoRequest request)
        {
            // TODO: refactor
            if (needConfirmation.Any())
            {
                var ackRequest = new TL.MsgsAckRequest(needConfirmation);
                using (var memory = new MemoryStream())
                    using (var writer = new TBinaryWriter(memory))
                    {
                        ackRequest.OnSend(writer);
                        await Send(memory.ToArray(), ackRequest);

                        needConfirmation.Clear();
                    }
            }


            using (var memory = new MemoryStream())
                using (var writer = new TBinaryWriter(memory))
                {
                    request.OnSend(writer);
                    await Send(memory.ToArray(), request);
                }

            _session.Save();
        }
コード例 #2
0
ファイル: Session.cs プロジェクト: DrEhsan/TeleTurk
        public byte[] ToBytes()
        {
            using (var stream = new MemoryStream())
                using (var writer = new TBinaryWriter(stream))
                {
                    writer.Write(Id);
                    writer.Write(Sequence);
                    writer.Write(Salt);
                    writer.Write(LastMessageId);
                    writer.Write(TimeOffset);
                    writer.Write(ServerAddress);
                    writer.Write(Port);

                    if (User != null)
                    {
                        writer.Write(true);
                        User.Write(writer);
                    }
                    else
                    {
                        writer.Write(false);
                    }

                    writer.Write(AuthKey.Data);

                    return(stream.ToArray());
                }
        }
コード例 #3
0
ファイル: Step2_DHExchange.cs プロジェクト: DrEhsan/TeleTurk
        public byte[] ToBytes(byte[] nonce, byte[] serverNonce, List <byte[]> fingerprints, BigInteger pq)
        {
            new Random().NextBytes(newNonce);

            var pqPair = Factorizator.Factorize(pq);

            byte[] reqDhParamsBytes;

            using (MemoryStream pqInnerData = new MemoryStream(255))
            {
                using (TBinaryWriter pqInnerDataWriter = new TBinaryWriter(pqInnerData))
                {
                    pqInnerDataWriter.Write(0x83c95aec); // pq_inner_data
                    pqInnerDataWriter.Write(pq.ToByteArrayUnsigned());
                    pqInnerDataWriter.Write(pqPair.Min.ToByteArrayUnsigned());
                    pqInnerDataWriter.Write(pqPair.Max.ToByteArrayUnsigned());
                    pqInnerDataWriter.WriteBase(nonce);
                    pqInnerDataWriter.WriteBase(serverNonce);
                    pqInnerDataWriter.WriteBase(newNonce);

                    byte[] ciphertext        = null;
                    byte[] targetFingerprint = null;
                    foreach (byte[] fingerprint in fingerprints)
                    {
                        ciphertext = RSA.Encrypt(BitConverter.ToString(fingerprint).Replace("-", string.Empty),
                                                 pqInnerData.GetBuffer(), 0, (int)pqInnerData.Position);
                        if (ciphertext != null)
                        {
                            targetFingerprint = fingerprint;
                            break;
                        }
                    }

                    if (ciphertext == null)
                    {
                        throw new InvalidOperationException(
                                  String.Format("not found valid key for fingerprints: {0}", String.Join(", ", fingerprints)));
                    }

                    using (MemoryStream reqDHParams = new MemoryStream(1024))
                    {
                        using (TBinaryWriter reqDHParamsWriter = new TBinaryWriter(reqDHParams))
                        {
                            reqDHParamsWriter.Write(0xd712e4be); // req_dh_params
                            reqDHParamsWriter.WriteBase(nonce);
                            reqDHParamsWriter.WriteBase(serverNonce);
                            reqDHParamsWriter.Write(pqPair.Min.ToByteArrayUnsigned());
                            reqDHParamsWriter.Write(pqPair.Max.ToByteArrayUnsigned());
                            reqDHParamsWriter.WriteBase(targetFingerprint);
                            reqDHParamsWriter.Write(ciphertext);

                            reqDhParamsBytes = reqDHParams.ToArray();
                        }
                    }
                }
                return(reqDhParamsBytes);
            }
        }
コード例 #4
0
        public byte[] ToBytes(byte[] nonce, byte[] serverNonce, byte[] newNonce, byte[] encryptedAnswer)
        {
            this.newNonce = newNonce;
            AESKeyData key = AES.GenerateKeyDataFromNonces(serverNonce, newNonce);

            byte[] plaintextAnswer = AES.DecryptAES(key, encryptedAnswer);

            // logger.debug("plaintext answer: {0}", BitConverter.ToString(plaintextAnswer));

            int        g;
            BigInteger dhPrime;
            BigInteger ga;

            using (MemoryStream dhInnerData = new MemoryStream(plaintextAnswer))
            {
                using (TBinaryReader dhInnerDataReader = new TBinaryReader(dhInnerData))
                {
                    byte[] hashsum = dhInnerDataReader.ReadBytes(20);
                    uint   code    = dhInnerDataReader.ReadUInt32();
                    if (code != 0xb5890dba)
                    {
                        throw new InvalidOperationException($"invalid dh_inner_data code: {code}");
                    }

                    // logger.debug("valid code");

                    byte[] nonceFromServer1 = dhInnerDataReader.ReadBytes(16);
                    if (!nonceFromServer1.SequenceEqual(nonce))
                    {
                        throw new InvalidOperationException("invalid nonce in encrypted answer");
                    }

                    // logger.debug("valid nonce");

                    byte[] serverNonceFromServer1 = dhInnerDataReader.ReadBytes(16);
                    if (!serverNonceFromServer1.SequenceEqual(serverNonce))
                    {
                        throw new InvalidOperationException("invalid server nonce in encrypted answer");
                    }

                    // logger.debug("valid server nonce");

                    g       = dhInnerDataReader.ReadInt32();
                    dhPrime = new BigInteger(1, dhInnerDataReader.ReadBytes());
                    ga      = new BigInteger(1, dhInnerDataReader.ReadBytes());

                    int serverTime = dhInnerDataReader.ReadInt32();
                    timeOffset = serverTime - (int)(Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds) / 1000);

                    // logger.debug("g: {0}, dhprime: {1}, ga: {2}", g, dhPrime, ga);
                }
            }

            BigInteger b  = new BigInteger(2048, new Random());
            BigInteger gb = BigInteger.ValueOf(g).ModPow(b, dhPrime);

            _gab = ga.ModPow(b, dhPrime);

            // logger.debug("gab: {0}", gab);

            // prepare client dh inner data
            byte[] clientDHInnerDataBytes;
            using (MemoryStream clientDhInnerData = new MemoryStream())
            {
                using (TBinaryWriter clientDhInnerDataWriter = new TBinaryWriter(clientDhInnerData))
                {
                    clientDhInnerDataWriter.Write(0x6643b654); // client_dh_inner_data
                    clientDhInnerDataWriter.WriteBase(nonce);
                    clientDhInnerDataWriter.WriteBase(serverNonce);
                    clientDhInnerDataWriter.Write((long)0); // TODO: retry_id
                    clientDhInnerDataWriter.Write(gb.ToByteArrayUnsigned());

                    using (MemoryStream clientDhInnerDataWithHash = new MemoryStream())
                    {
                        using (BinaryWriter clientDhInnerDataWithHashWriter = new BinaryWriter(clientDhInnerDataWithHash))
                        {
                            using (SHA1 sha1 = new SHA1Managed())
                            {
                                clientDhInnerDataWithHashWriter.Write(sha1.ComputeHash(clientDhInnerData.GetBuffer(), 0, (int)clientDhInnerData.Position));
                                clientDhInnerDataWithHashWriter.Write(clientDhInnerData.GetBuffer(), 0, (int)clientDhInnerData.Position);
                                clientDHInnerDataBytes = clientDhInnerDataWithHash.ToArray();
                            }
                        }
                    }
                }
            }

            // logger.debug("client dh inner data papared len {0}: {1}", clientDHInnerDataBytes.Length, BitConverter.ToString(clientDHInnerDataBytes).Replace("-", ""));

            // encryption
            byte[] clientDhInnerDataEncryptedBytes = AES.EncryptAES(key, clientDHInnerDataBytes);

            // logger.debug("inner data encrypted {0}: {1}", clientDhInnerDataEncryptedBytes.Length, BitConverter.ToString(clientDhInnerDataEncryptedBytes).Replace("-", ""));

            // prepare set_client_dh_params
            byte[] setclientDhParamsBytes;
            using (MemoryStream setClientDhParams = new MemoryStream())
            {
                using (TBinaryWriter setClientDhParamsWriter = new TBinaryWriter(setClientDhParams))
                {
                    setClientDhParamsWriter.Write(0xf5045f1f);
                    setClientDhParamsWriter.WriteBase(nonce);
                    setClientDhParamsWriter.WriteBase(serverNonce);
                    setClientDhParamsWriter.Write(clientDhInnerDataEncryptedBytes);

                    setclientDhParamsBytes = setClientDhParams.ToArray();
                }
            }

            // logger.debug("set client dh params prepared: {0}", BitConverter.ToString(setclientDhParamsBytes));

            return(setclientDhParamsBytes);
        }