private Tuple <byte[], ulong, int> DecodeMessage(byte[] body) { byte[] message; ulong remoteMessageId; int remoteSequence; using (var inputStream = new MemoryStream(body)) using (var inputReader = new BinaryReader(inputStream)) { if (inputReader.BaseStream.Length < 8) { throw new InvalidOperationException($"Can't decode packet"); } ulong remoteAuthKeyId = inputReader.ReadUInt64(); // TODO: check auth key id byte[] msgKey = inputReader.ReadBytes(16); // TODO: check msg_key correctness AESKeyData keyData = Helpers.CalcKey(_session.AuthKey.Data, msgKey, false); byte[] plaintext = AES.DecryptAES(keyData, inputReader.ReadBytes((int)(inputStream.Length - inputStream.Position))); using (MemoryStream plaintextStream = new MemoryStream(plaintext)) using (BinaryReader plaintextReader = new BinaryReader(plaintextStream)) { var remoteSalt = plaintextReader.ReadUInt64(); var remoteSessionId = plaintextReader.ReadUInt64(); remoteMessageId = plaintextReader.ReadUInt64(); remoteSequence = plaintextReader.ReadInt32(); int msgLen = plaintextReader.ReadInt32(); message = plaintextReader.ReadBytes(msgLen); } } return(new Tuple <byte[], ulong, int>(message, remoteMessageId, remoteSequence)); }
public override async Task <bool> SendMessage(string message) { try { logger.info("send message with key: {0}", BitConverter.ToString(key).Replace("-", "").ToLower()); long messageId = Helpers.GenerateRandomLong(); DecryptedMessage msg = TL.decryptedMessage(messageId, Helpers.GenerateRandomBytes(128), message, TL.decryptedMessageMediaEmpty()); byte[] data; using (MemoryStream memory = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(memory)) { msg.Write(writer); data = memory.ToArray(); } } using (MemoryStream memory = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(memory)) { writer.Write(data.Length); writer.Write(data); data = memory.ToArray(); } } byte[] msgKey = Helpers.CalcMsgKey(data); AESKeyData aesKey = Helpers.CalcKey(key, msgKey, true); data = AES.EncryptAES(aesKey, data); using (MemoryStream memory = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(memory)) { writer.Write(fingerprint); writer.Write(msgKey); writer.Write(data); data = memory.ToArray(); } } Messages_sentEncryptedMessageConstructor sent = (Messages_sentEncryptedMessageConstructor)await session.Api.messages_sendEncrypted(InputEncryptedChat, messageId, data); MessageModel messageModel = new MessageModelEncryptedDelivered(TelegramSession.Instance.SelfId, OpponentId, sent.date, true, true, msg, TL.encryptedFileEmpty()); messages.Add(messageModel); TelegramSession.Instance.Dialogs.Model.UpDialog(this); return(true); } catch (Exception e) { logger.error("send encrypted message exception: {0}", e); return(false); } }
private void GatewayOnInput(object sender, byte[] data) { ulong remoteSalt; ulong remoteSessionId; ulong remoteMessageId; int remoteSequence; byte[] message; using (MemoryStream inputStream = new MemoryStream(data)) using (BinaryReader inputReader = new BinaryReader(inputStream)) { ulong remoteAuthKeyId = inputReader.ReadUInt64(); // TODO: check auth key id byte[] msgKey = inputReader.ReadBytes(16); // TODO: check msg_key correctness AESKeyData keyData = Helpers.CalcKey(dc.AuthKey.Data, msgKey, false); byte[] plaintext = AES.DecryptAES(keyData, inputReader.ReadBytes((int)(inputStream.Length - inputStream.Position))); using (MemoryStream plaintextStream = new MemoryStream(plaintext)) using (BinaryReader plaintextReader = new BinaryReader(plaintextStream)) { remoteSalt = plaintextReader.ReadUInt64(); remoteSessionId = plaintextReader.ReadUInt64(); remoteMessageId = plaintextReader.ReadUInt64(); remoteSequence = plaintextReader.ReadInt32(); int msgLen = plaintextReader.ReadInt32(); message = plaintextReader.ReadBytes(msgLen); } logger.info("gateway on input: {0}", BitConverter.ToString(message).Replace("-", "").ToLower()); } using (MemoryStream messageStream = new MemoryStream(message, false)) using (BinaryReader messageReader = new BinaryReader(messageStream)) { try { processMessage(remoteMessageId, remoteSequence, messageReader); } catch (Exception e) { logger.error("failed to process message: {0}", e); } } }
public static byte[] PrepareToSend2(byte[] message, ulong authKeyId, ulong salt, ulong sessionId, ulong messageId, byte[] servernonce, int sequenceNumber, AuthKey authKey) { using (var memoryStream = new MemoryStream()) { using (var binaryWriter = new BinaryWriter(memoryStream)) { //binaryWriter.Write(servernonce); binaryWriter.Write(salt); //salt binaryWriter.Write(sessionId); //sessionId binaryWriter.Write(messageId); //messageid binaryWriter.Write(sequenceNumber); binaryWriter.Write(message.Length); binaryWriter.Write(message); message = memoryStream.ToArray(); } } byte[] msgKey = Helpers.CalcMsgKey(message); AESKeyData key = Helpers.CalcKey(authKey.Data, msgKey, false); message = AES.EncryptAES(key, message); using (var memoryStream = new MemoryStream()) { using (var binaryWriter = new BinaryWriter(memoryStream)) { binaryWriter.Write(authKeyId); binaryWriter.Write(msgKey); binaryWriter.Write(message); return(memoryStream.ToArray()); } } }
public async Task <(EncryptedData, MemoryStream)> EncryptToStream(Stream stream) { AES.GenerateIV(); AES.GenerateKey(); var msEncrypt = new MemoryStream(); using (var encryptor = AES.CreateEncryptor()) using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { await stream.CopyToAsync(csEncrypt); } var aesKeyData = new AESKeyData { IV = AES.IV, Key = AES.Key }; var aesKeyDataBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(aesKeyData)); var encryptedData = new EncryptedData { RSAEncryptedAESKey = RSA.Encrypt(aesKeyDataBytes, RSAEncryptionPadding.Pkcs1) }; return(encryptedData, msEncrypt); }
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 (BinaryReader dhInnerDataReader = new BinaryReader(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, Serializers.Bytes.read(dhInnerDataReader)); ga = new BigInteger(1, Serializers.Bytes.read(dhInnerDataReader)); 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 (BinaryWriter clientDhInnerDataWriter = new BinaryWriter(clientDhInnerData)) { clientDhInnerDataWriter.Write(0x6643b654); // client_dh_inner_data clientDhInnerDataWriter.Write(nonce); clientDhInnerDataWriter.Write(serverNonce); clientDhInnerDataWriter.Write((long)0); // TODO: retry_id Serializers.Bytes.write(clientDhInnerDataWriter, 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 (BinaryWriter setClientDhParamsWriter = new BinaryWriter(setClientDhParams)) { setClientDhParamsWriter.Write(0xf5045f1f); setClientDhParamsWriter.Write(nonce); setClientDhParamsWriter.Write(serverNonce); Serializers.Bytes.write(setClientDhParamsWriter, clientDhInnerDataEncryptedBytes); setclientDhParamsBytes = setClientDhParams.ToArray(); } } // logger.debug("set client dh params prepared: {0}", BitConverter.ToString(setclientDhParamsBytes)); return(setclientDhParamsBytes); }
public async Task <AuthKey> Generate(TelegramDC dc, int maxRetries) { ConnectedEvent += delegate {}; await ConnectAsync(dc, maxRetries); random.NextBytes(nonce); using (MemoryStream memoryStream = new MemoryStream()) { using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) { binaryWriter.Write(0x60469778); binaryWriter.Write(nonce); Send(memoryStream.ToArray()); } } completionSource = new TaskCompletionSource <byte[]>(); byte[] response = await completionSource.Task; BigInteger pq; List <byte[]> fingerprints = new List <byte[]>(); using (var memoryStream = new MemoryStream(response, false)) { using (var binaryReader = new BinaryReader(memoryStream)) { int responseCode = binaryReader.ReadInt32(); if (responseCode != 0x05162463) { logger.error("invalid response code: {0}", responseCode); return(null); } byte[] nonceFromServer = binaryReader.ReadBytes(16); if (!nonceFromServer.SequenceEqual(nonce)) { logger.debug("invalid nonce from server"); return(null); } serverNonce = binaryReader.ReadBytes(16); byte[] pqbytes = Serializers.Bytes.read(binaryReader); pq = new BigInteger(1, pqbytes); int vectorId = binaryReader.ReadInt32(); if (vectorId != 0x1cb5c415) { logger.debug("invalid fingerprints vector id: {0}", vectorId); return(null); } int fingerprintCount = binaryReader.ReadInt32(); for (int i = 0; i < fingerprintCount; i++) { byte[] fingerprint = binaryReader.ReadBytes(8); fingerprints.Add(fingerprint); } } } FactorizedPair pqPair = Factorizator.Factorize(pq); logger.debug("stage 1: ok"); random.NextBytes(newNonce); byte[] reqDhParamsBytes; using (MemoryStream pqInnerData = new MemoryStream(255)) { using (BinaryWriter pqInnerDataWriter = new BinaryWriter(pqInnerData)) { pqInnerDataWriter.Write(0x83c95aec); // pq_inner_data Serializers.Bytes.write(pqInnerDataWriter, pq.ToByteArrayUnsigned()); Serializers.Bytes.write(pqInnerDataWriter, pqPair.Min.ToByteArrayUnsigned()); Serializers.Bytes.write(pqInnerDataWriter, pqPair.Max.ToByteArrayUnsigned()); pqInnerDataWriter.Write(nonce); pqInnerDataWriter.Write(serverNonce); pqInnerDataWriter.Write(newNonce); logger.debug("pq_inner_data: {0}", BitConverter.ToString(pqInnerData.GetBuffer())); 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) { logger.error("not found valid key for fingerprints: {0}", String.Join(", ", fingerprints)); return(null); } using (MemoryStream reqDHParams = new MemoryStream(1024)) { using (BinaryWriter reqDHParamsWriter = new BinaryWriter(reqDHParams)) { reqDHParamsWriter.Write(0xd712e4be); // req_dh_params reqDHParamsWriter.Write(nonce); reqDHParamsWriter.Write(serverNonce); Serializers.Bytes.write(reqDHParamsWriter, pqPair.Min.ToByteArrayUnsigned()); Serializers.Bytes.write(reqDHParamsWriter, pqPair.Max.ToByteArrayUnsigned()); reqDHParamsWriter.Write(targetFingerprint); Serializers.Bytes.write(reqDHParamsWriter, ciphertext); logger.debug("sending req_dh_paras: {0}", BitConverter.ToString(reqDHParams.ToArray())); reqDhParamsBytes = reqDHParams.ToArray(); } } } } completionSource = new TaskCompletionSource <byte[]>(); Send(reqDhParamsBytes); response = await completionSource.Task; logger.debug("dh response: {0}", BitConverter.ToString(response)); byte[] encryptedAnswer; using (MemoryStream responseStream = new MemoryStream(response, false)) { using (BinaryReader responseReader = new BinaryReader(responseStream)) { uint responseCode = responseReader.ReadUInt32(); if (responseCode == 0x79cb045d) { // server_DH_params_fail logger.error("server_DH_params_fail: TODO"); return(null); } if (responseCode != 0xd0e8075c) { logger.error("invalid response code: {0}", responseCode); return(null); } byte[] nonceFromServer = responseReader.ReadBytes(16); if (!nonceFromServer.SequenceEqual(nonce)) { logger.debug("invalid nonce from server"); return(null); } byte[] serverNonceFromServer = responseReader.ReadBytes(16); if (!serverNonceFromServer.SequenceEqual(serverNonce)) { logger.error("invalid server nonce from server"); return(null); } encryptedAnswer = Serializers.Bytes.read(responseReader); } } logger.debug("encrypted answer: {0}", BitConverter.ToString(encryptedAnswer)); 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 (BinaryReader dhInnerDataReader = new BinaryReader(dhInnerData)) { byte[] hashsum = dhInnerDataReader.ReadBytes(20); uint code = dhInnerDataReader.ReadUInt32(); if (code != 0xb5890dba) { logger.error("invalid dh_inner_data code: {0}", code); return(null); } logger.debug("valid code"); byte[] nonceFromServer1 = dhInnerDataReader.ReadBytes(16); if (!nonceFromServer1.SequenceEqual(nonce)) { logger.error("invalid nonce in encrypted answer"); return(null); } logger.debug("valid nonce"); byte[] serverNonceFromServer1 = dhInnerDataReader.ReadBytes(16); if (!serverNonceFromServer1.SequenceEqual(serverNonce)) { logger.error("invalid server nonce in encrypted answer"); return(null); } logger.debug("valid server nonce"); g = dhInnerDataReader.ReadInt32(); dhPrime = new BigInteger(1, Serializers.Bytes.read(dhInnerDataReader)); ga = new BigInteger(1, Serializers.Bytes.read(dhInnerDataReader)); 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, random); BigInteger gb = BigInteger.ValueOf(g).ModPow(b, dhPrime); BigInteger gab = ga.ModPow(b, dhPrime); logger.debug("gab: {0}", gab); // prepare client dh inner data byte[] clientDHInnerDataBytes; using (MemoryStream clientDhInnerData = new MemoryStream()) { using (BinaryWriter clientDhInnerDataWriter = new BinaryWriter(clientDhInnerData)) { clientDhInnerDataWriter.Write(0x6643b654); // client_dh_inner_data clientDhInnerDataWriter.Write(nonce); clientDhInnerDataWriter.Write(serverNonce); clientDhInnerDataWriter.Write((long)0); // TODO: retry_id Serializers.Bytes.write(clientDhInnerDataWriter, 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 (BinaryWriter setClientDhParamsWriter = new BinaryWriter(setClientDhParams)) { setClientDhParamsWriter.Write(0xf5045f1f); setClientDhParamsWriter.Write(nonce); setClientDhParamsWriter.Write(serverNonce); Serializers.Bytes.write(setClientDhParamsWriter, clientDhInnerDataEncryptedBytes); setclientDhParamsBytes = setClientDhParams.ToArray(); } } logger.debug("set client dh params prepared: {0}", BitConverter.ToString(setclientDhParamsBytes)); completionSource = new TaskCompletionSource <byte[]>(); Send(setclientDhParamsBytes); response = await completionSource.Task; using (MemoryStream responseStream = new MemoryStream(response)) { using (BinaryReader responseReader = new BinaryReader(responseStream)) { uint code = responseReader.ReadUInt32(); if (code == 0x3bcbf734) // dh_gen_ok { logger.debug("dh_gen_ok"); byte[] nonceFromServer = responseReader.ReadBytes(16); if (!nonceFromServer.SequenceEqual(nonce)) { logger.error("invalid nonce"); return(null); } byte[] serverNonceFromServer = responseReader.ReadBytes(16); if (!serverNonceFromServer.SequenceEqual(serverNonce)) { logger.error("invalid server nonce"); return(null); } byte[] newNonceHash1 = responseReader.ReadBytes(16); logger.debug("new nonce hash 1: {0}", BitConverter.ToString(newNonceHash1)); AuthKey authKey = new AuthKey(gab); byte[] newNonceHashCalculated = authKey.CalcNewNonceHash(newNonce, 1); if (!newNonceHash1.SequenceEqual(newNonceHashCalculated)) { logger.error("invalid new nonce hash"); return(null); } logger.info("generated new auth key: {0}", gab); logger.info("saving time offset: {0}", timeOffset); TelegramSession.Instance.TimeOffset = timeOffset; return(authKey); } else if (code == 0x46dc1fb9) // dh_gen_retry { logger.debug("dh_gen_retry"); return(null); } else if (code == 0xa69dae02) { // dh_gen_fail logger.debug("dh_gen_fail"); return(null); } else { logger.debug("dh_gen unknown: {0}", code); return(null); } } } }
// in background thread public void ReceiveMessage(EncryptedMessage encryptedMessage) { try { if (encryptedMessage.Constructor == Constructor.encryptedMessage) { logger.info("simple encrypted message"); EncryptedMessageConstructor encryptedMessageConstructor = (EncryptedMessageConstructor)encryptedMessage; byte[] data = encryptedMessageConstructor.bytes; byte[] msgKey; long keyFingerprint; logger.info("encrypted message data: {0}", BitConverter.ToString(data).Replace("-", "").ToLower()); using (MemoryStream memory = new MemoryStream(data)) { using (BinaryReader reader = new BinaryReader(memory)) { keyFingerprint = reader.ReadInt64(); msgKey = reader.ReadBytes(16); data = reader.ReadBytes(data.Length - 16 - 8); } } if (fingerprint != keyFingerprint) { logger.error("invalid key fingerprint"); return; } logger.info("ciphertext data: {0}", BitConverter.ToString(data).Replace("-", "").ToLower()); AESKeyData aesKey = Helpers.CalcKey(key, msgKey, true); data = AES.DecryptAES(aesKey, data); byte[] data2 = AES.EncryptAES(aesKey, data); byte[] data3 = AES.DecryptAES(aesKey, data2); logger.info("aes equals: {0}", data.SequenceEqual(data3)); logger.info("plaintext data: {0}", BitConverter.ToString(data).Replace("-", "").ToLower()); logger.info("two-transformed plaintext: {0}", BitConverter.ToString(data3).Replace("-", "").ToLower()); byte[] calculatedMsgKey; using (MemoryStream memory = new MemoryStream(data)) { using (BinaryReader reader = new BinaryReader(memory)) { int len = reader.ReadInt32(); logger.info("readed len = {0}, actual len = {1}", len, data.Length - 4); if (len < 0 || len > data.Length - 4) { return; } calculatedMsgKey = Helpers.CalcMsgKey(data, 0, 4 + len); data = reader.ReadBytes(len); } } if (!msgKey.SequenceEqual(calculatedMsgKey)) { logger.info("incalid msg key: data {0}, sha1 {1}, received msg key {2}", BitConverter.ToString(data), BitConverter.ToString(Helpers.sha1(data)), BitConverter.ToString(msgKey)); return; } DecryptedMessage decryptedMessage; using (MemoryStream memory = new MemoryStream(data)) { using (BinaryReader reader = new BinaryReader(memory)) { //DecryptedMessageLayerConstructor layer = (DecryptedMessageLayerConstructor) TL.Parse<DecryptedMessageLayer>(reader); // if(layer.layer > 8) { // logger.info("encrypted message layer {0} - need upgrade", layer.layer); // // TODO: notify - need upgrade // return; // } decryptedMessage = TL.Parse <DecryptedMessage>(reader); } } logger.info("decrypted message: {0}", decryptedMessage); if (decryptedMessage.Constructor == Constructor.decryptedMessageService) { DecryptedMessageAction action = ((DecryptedMessageServiceConstructor)decryptedMessage).action; if (action.Constructor == Constructor.decryptedMessageActionSetMessageTTL) { DecryptedMessageActionSetMessageTTLConstructor actionttl = (DecryptedMessageActionSetMessageTTLConstructor)action; UpdateTTL(actionttl.ttl_seconds); } } MessageModel messageModel = new MessageModelEncryptedDelivered(OpponentId, TelegramSession.Instance.SelfId, encryptedMessageConstructor.date, false, true, decryptedMessage, encryptedMessageConstructor.file); Deployment.Current.Dispatcher.BeginInvoke(() => { messages.Add(messageModel); if (this == TelegramSession.Instance.Dialogs.OpenedDialog) { OpenedRead(); } }); } } catch (Exception e) { logger.error("dialog model receive encrypted message exception: {0}", e); } }
private static void ProcessRequest(TcpListener tcpListener) { Console.WriteLine("Processing..."); var tcpClient = tcpListener.AcceptTcpClient(); var netStream = tcpClient.GetStream(); BigInteger ga = null; byte[] newNonce = new byte[32]; BigInteger a = new BigInteger(2048, new Random()); var dhPrime = new BigInteger("00C150023E2F70DB7985DED064759CFECF0AF328E69A41DAF4D6F01B538135A6F91F8F8B2A0EC9BA9720CE352EFCF6C5680FFC424BD634864902DE0B4BD6D49F4E580230E3AE97D95C8B19442B3C0A10D8F5633FECEDD6926A7F6DAB0DDB7D457F9EA81B8465FCD6FFFEED114011DF91C059CAEDAF97625F6C96ECC74725556934EF781D866B34F011FCE4D835A090196E9A5F0E4449AF7EB697DDB9076494CA5F81104A305B6DD27665722C46B60E5DF680FB16B210607EF217652E60236C255F6A28315F4083A96791D7214BF64C1DF4FD0DB1944FB26A2A57031B32EEE64AD15A8BA68885CDE74A5BFC920F6ABF59BA5C75506373E7130F9042DA922179251F", 16); BigInteger gb = null; var sequenceNumber = 1; ulong? messageId = null; var privateKey = new BigInteger("582A4D5EE3A45C1AEEBDECD549D1FD4E12337B05C4C0A03FA8FF4A0A7B2861BAB86E8B58A70AAB9CF173FA313348239E28B17D34C7CEC8B68544BAD8623A306D747B7DC1D3D064FA73CE96893E8AFC36F7CDF58A383F48BDEC284D30BFFBC3F1A413DC869B3692EDD26004EE661C021BDA32F124D6631C67891E3E35EEDEAA08BFED8DBB7A6CC1D550CF16C67703BBDFFF0500FD81A55F98D92ECD67CE3CC31B766EA0DFBA284E18677E46036D9ED04105AAD11E97FD675F49A3B54D5AD395AA3C5B8343CDFF70C2E2A9243A47FBC5F541BBAE910B5DD1BF574B1E732A105C2B8F5239A4DFA0BCE0559F18BA0C44D31A279FA7CDCA612BD8F9796EBD114F7FA9", 16); AuthKey authKey = null; //var getingCounter = 0; //while (true) //{ // if (!netStream.DataAvailable) // continue; // Console.WriteLine("Get data " + ++getingCounter); //} while (tcpClient.Connected) { System.Threading.Thread.Sleep(100); if (!netStream.DataAvailable) { continue; } byte[] nonceFromClient = new byte[16]; byte[] servernonce = new byte[16]; uint responseCode = 0; int innerCode = 0; long authkeysample = 123456789; const long step1Constructor = 0x60469778; const long step2Constructor = 0xd712e4be; const long step3Constructor = 0xf5045f1f; if (netStream.CanRead) { var bytes = new byte[tcpClient.ReceiveBufferSize]; netStream.Read(bytes, 0, (int)tcpClient.ReceiveBufferSize); var tcpMessage = TcpMessage.Decode(bytes); var binaryReader = new BinaryReader(new MemoryStream(tcpMessage.Body, false)); var authKeyId = binaryReader.ReadInt64(); if (authKeyId == 0) { var msgId = binaryReader.ReadInt64(); var datalength = binaryReader.ReadInt32(); var data = binaryReader.ReadBytes(datalength); var binaryReader2 = new BinaryReader(new MemoryStream(data, false)); responseCode = binaryReader2.ReadUInt32(); Console.WriteLine("Request code: " + responseCode); if (responseCode == step1Constructor) //---Step1_PQRequest { nonceFromClient = binaryReader2.ReadBytes(16); } else if (responseCode == step2Constructor) //---Step1_PQRequest { nonceFromClient = binaryReader2.ReadBytes(16); servernonce = binaryReader2.ReadBytes(16); var p = binaryReader2.ReadBytes(4); var q = binaryReader2.ReadBytes(8); var targetFingerprint = BitConverter.ToString(binaryReader2.ReadBytes(8)).Replace("-", string.Empty); //TODO: need to decryption var ciphertext = Bytes.read(binaryReader2); ciphertext = RSA.Decrypt(targetFingerprint, ciphertext, privateKey, 0, ciphertext.Length); var cipherReader = new BinaryReader(new MemoryStream(ciphertext, false)); var hashsum = cipherReader.ReadBytes(20); var innercode = cipherReader.ReadUInt32();//0x83c95aec var pq = cipherReader.ReadBytes(20); var noncetemp = cipherReader.ReadBytes(16); var servernoncetemp = cipherReader.ReadBytes(16); newNonce = cipherReader.ReadBytes(32); //Array.Copy(ciphertext, ciphertext.Length - 32, newNonce, 0, 32); //ciphertext.CopyTo(newnoncetemp, ciphertext.Length - 32); } else if (responseCode == step3Constructor) //---Step1_PQRequest { nonceFromClient = binaryReader2.ReadBytes(16); servernonce = binaryReader2.ReadBytes(16); //TODO: need to decryption var ciphertext = Bytes.read(binaryReader2); AESKeyData key = AES.GenerateKeyDataFromNonces(servernonce, newNonce); var cleartext = AES.DecryptAES(key, ciphertext); var binaryReadernner = new BinaryReader(new MemoryStream(cleartext, false)); var hasheddata = binaryReadernner.ReadBytes(20); var client_dh_inner_data_code = binaryReadernner.ReadUInt32(); if (client_dh_inner_data_code != 0x6643b654) { throw new Exception("We have a complex story"); } var nonceFromClient_temp = binaryReadernner.ReadBytes(16); var servernonce_temp = binaryReadernner.ReadBytes(16); var zero = binaryReadernner.ReadUInt64(); gb = new BigInteger(Bytes.read(binaryReadernner)); } } else { var _gba = gb.ModPow(a, dhPrime); authKey = new AuthKey(_gba); var decodeMessage = DecodeMessage(tcpMessage.Body, authKey); var objrawReader = new BinaryReader(new MemoryStream(decodeMessage.Item1, false)); messageId = decodeMessage.Item2; innerCode = objrawReader.ReadInt32(); if (innerCode == 0x62d6b459)//acknowledged { var vector = objrawReader.ReadInt32(); var msgCount = objrawReader.ReadInt32(); continue; } else //if (responseCode == -627372787) { objrawReader.BaseStream.Position += -4; var obj = ObjectUtils.DeserializeObject(objrawReader); if (obj is TLRequestInvokeWithLayer) { var invokewithlayer = (TLRequestInvokeWithLayer)obj; if (invokewithlayer.Query is TLRequestInitConnection) { var requestInitConnection = (TLRequestInitConnection)invokewithlayer.Query; } else if (invokewithlayer.Query is TLRequestSendCode) { var requestSendCode = (TLRequestSendCode)invokewithlayer.Query; } } else if (obj is TLRequestSendCode) { var requestSendCode = (TLRequestSendCode)obj; } else if (obj is TLRequestSignIn) { var requestSignIn = (TLRequestSignIn)obj; } else if (obj is TLRequestGetContacts) { var requestGetContacts = (TLRequestGetContacts)obj; } } //var keyData = Helpers.CalcKey(buffer, messageKey, false); //var data = AES.DecryptAES(keyData, buffer); } } if (netStream.CanWrite) { var fingerprint = StringToByteArray("216be86c022bb4c3"); byte[] outputdata = null; if (responseCode == step1Constructor) { var nonce = new byte[16]; new Random().NextBytes(nonce); outputdata = new Step1_Response() { Pq = new BigInteger(1, BitConverter.GetBytes(880)), ServerNonce = nonceFromClient, Nonce = nonce, Fingerprints = new List <byte[]>() { fingerprint } }.ToBytes(); } else if (responseCode == step2Constructor) { //var nonce = new byte[16]; //new Random().NextBytes(nonce); byte[] answer; var hashsum = Encoding.UTF8.GetBytes("asdfghjklmnbvcxzasdf"); const uint innerCodetemp = 0xb5890dba; AESKeyData key = AES.GenerateKeyDataFromNonces(servernonce, newNonce); var g = 47; ga = BigInteger.ValueOf(g).ModPow(a, dhPrime); using (var memoryStream = new MemoryStream()) { using (var binaryWriter = new BinaryWriter(memoryStream)) { binaryWriter.Write(hashsum); binaryWriter.Write(innerCodetemp); binaryWriter.Write(nonceFromClient); binaryWriter.Write(servernonce); binaryWriter.Write(g); Bytes.write(binaryWriter, dhPrime.ToByteArrayUnsigned()); Bytes.write(binaryWriter, ga.ToByteArrayUnsigned()); Bytes.write(binaryWriter, BitConverter.GetBytes((int)(Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds) / 1000)));//server datetime answer = memoryStream.ToArray(); } } outputdata = new Step2_Response() { ServerNonce = nonceFromClient, Nonce = servernonce, NewNonce = newNonce, EncryptedAnswer = AES.EncryptAES(key, answer) }.ToBytes(); } else if (responseCode == step3Constructor) { var _gba = gb.ModPow(a, dhPrime); authKey = new AuthKey(_gba); var newNonceHash = authKey.CalcNewNonceHash(newNonce, 1); const uint innerCodeTemp = 0x3bcbf734; using (var memoryStream = new MemoryStream()) { using (var binaryWriter = new BinaryWriter(memoryStream)) { binaryWriter.Write(innerCodeTemp); binaryWriter.Write(servernonce); binaryWriter.Write(nonceFromClient); binaryWriter.Write(newNonceHash);//hashnewnonce outputdata = memoryStream.ToArray(); } } } else if (innerCode == -2035355412)//TLRequestSendCode { #region Generate TLSentCode var sentCode = new TLSentCode(); sentCode.PhoneRegistered = false; sentCode.Timeout = 7777; sentCode.PhoneCodeHash = "asdfghjklmnbvcxzasdf"; sentCode.Flags = 3; sentCode.NextType = new TLCodeTypeSms(); sentCode.Type = new TLSentCodeTypeApp() { Length = 20 }; #endregion using (var memoryStream = new MemoryStream()) { using (var binaryWriter = new BinaryWriter(memoryStream)) { binaryWriter.Write(0xf35c6d01); //main code binaryWriter.Write(messageId.Value); //requestId -- ulong -- from mesage id sentCode.SerializeBody(binaryWriter); outputdata = memoryStream.ToArray(); } } } else if (innerCode == -627372787) { #region Generate TLConfig //---Genrate mock tlconfig var config = new TLConfig(); config.CallConnectTimeoutMs = 7777; config.CallPacketTimeoutMs = 7777; config.CallReceiveTimeoutMs = 7777; config.CallRingTimeoutMs = 7777; config.ChatBigSize = 7777; config.ChatSizeMax = 777; config.Date = Convert.ToInt32((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds); config.DcOptions = new TLVector <TLDcOption>() { new TLDcOption() { Flags = 0, Id = 1, IpAddress = "127.0.0.1", Port = 5000 } }; config.DisabledFeatures = new TLVector <TLDisabledFeature>(); config.ForwardedCountMax = 777; config.MegagroupSizeMax = 777; config.NotifyCloudDelayMs = 7777; config.NotifyDefaultDelayMs = 7777; config.OfflineBlurTimeoutMs = 7777; config.OfflineIdleTimeoutMs = 7777; config.OnlineCloudTimeoutMs = 7777; config.OnlineUpdatePeriodMs = 7777; config.PhonecallsEnabled = false; config.PinnedDialogsCountMax = 7; config.PushChatLimit = 7; config.PushChatPeriodMs = 777; config.RatingEDecay = 777; config.SavedGifsLimit = 777; config.StickersRecentLimit = 777; config.ThisDc = 1;//TODO: ---what's this?!--- config.MeUrlPrefix = "https://t.me/"; config.TestMode = false; #endregion using (var memoryStream = new MemoryStream()) { using (var binaryWriter = new BinaryWriter(memoryStream)) { binaryWriter.Write(0xf35c6d01); //main code //binaryWriter.Write(0xf35c6d02);//code binaryWriter.Write(messageId.Value); //requestId -- ulong -- from mesage id //binaryWriter.Write(0x2144ca17);//innercode -- int //binaryWriter.Write(1123456789);//sample code //Serializers.Bytes.write(binaryWriter, config.Serialize()); config.SerializeBody(binaryWriter); outputdata = memoryStream.ToArray(); } } } else if (innerCode == -1126886015) { #region Generate TLAuthorization var auth = new TeleSharp.TL.Auth.TLAuthorization(); auth.Flags = 3; auth.User = new TLUser() { FirstName = "Meysami" }; #endregion using (var memoryStream = new MemoryStream()) { using (var binaryWriter = new BinaryWriter(memoryStream)) { binaryWriter.Write(0xf35c6d01); //main code binaryWriter.Write(messageId.Value); //requestId -- ulong -- from mesage id auth.SerializeBody(binaryWriter); outputdata = memoryStream.ToArray(); } } } else if (innerCode == 583445000)//GetContacts { #region Generate TLAbsContacts var contacts = new TLContacts(); contacts.Contacts = new TLVector <TLContact>() { new TLContact() { UserId = 11 }, new TLContact() { UserId = 12 } }; contacts.Users = new TLVector <TLAbsUser>() { new TLUser() { Bot = false, FirstName = "Mary", Id = 11 }, new TLUser() { Bot = false, FirstName = "Mary 2", Id = 12 } }; #endregion using (var memoryStream = new MemoryStream()) { using (var binaryWriter = new BinaryWriter(memoryStream)) { binaryWriter.Write(0xf35c6d01); //main code binaryWriter.Write(messageId.Value); //requestId -- ulong -- from mesage id contacts.SerializeBody(binaryWriter); outputdata = memoryStream.ToArray(); } } } else { continue; } if (innerCode != 0) { outputdata = PrepareToSend2(outputdata, authKey.Id, 0, 0, 0, servernonce, sequenceNumber, authKey); } else { outputdata = PrepareToSend(outputdata); } outputdata = Encode(outputdata, sequenceNumber++); netStream.Write(outputdata, 0, outputdata.Length); } else { Console.WriteLine("You cannot write data to this stream."); tcpClient.Close(); netStream.Close(); } } }