diff --git a/src/Client.cs b/src/Client.cs index 05558f8..8d6c512 100644 --- a/src/Client.cs +++ b/src/Client.cs @@ -437,9 +437,10 @@ namespace WTelegram _dcSession.ServerTicksOffset = (msgId >> 32) * 10000000 - DateTime.UtcNow.Ticks + 621355968000000000L; var msgStamp = MsgIdToStamp(_lastRecvMsgId = msgId); - if (serverSalt != _dcSession.Salt && serverSalt != _dcSession.Salts?.Values.ElementAtOrDefault(1)) + if (serverSalt != _dcSession.Salt && serverSalt != _dcSession.OldSalt && serverSalt != _dcSession.Salts?.Values.ElementAtOrDefault(1)) { Helpers.Log(3, $"{_dcSession.DcID}>Server salt has changed: {_dcSession.Salt:X} -> {serverSalt:X}"); + _dcSession.OldSalt = _dcSession.Salt; _dcSession.Salt = serverSalt; if (++_saltChangeCounter >= 10) throw new WTException("Server salt changed too often! Security issue?"); @@ -490,7 +491,7 @@ namespace WTelegram var keys = _dcSession.Salts.Keys; if (keys[^1] == DateTime.MaxValue) return; // GetFutureSalts ongoing var now = DateTime.UtcNow.AddTicks(_dcSession.ServerTicksOffset); - for (; keys.Count > 1 && keys[1] < now; _dcSession.Salt = _dcSession.Salts.Values[0]) + for (; keys.Count > 1 && keys[1] < now; _dcSession.OldSalt = _dcSession.Salt, _dcSession.Salt = _dcSession.Salts.Values[0]) _dcSession.Salts.RemoveAt(0); if (_dcSession.Salts.Count > 48) return; } @@ -503,6 +504,7 @@ namespace WTelegram _dcSession.Salts.Remove(DateTime.MaxValue); foreach (var entry in gfs.Result.salts) _dcSession.Salts[entry.valid_since] = entry.salt; + _dcSession.OldSalt = _dcSession.Salt; _dcSession.Salt = _dcSession.Salts.Values[0]; _session.Save(); } @@ -695,6 +697,7 @@ namespace WTelegram } break; case 48: // incorrect server salt (in this case, the bad_server_salt response is received with the correct salt, and the message is to be re-sent with it) + _dcSession.OldSalt = _dcSession.Salt; _dcSession.Salt = ((BadServerSalt)badMsgNotification).new_server_salt; CheckSalt(); break; diff --git a/src/Encryption.cs b/src/Encryption.cs index b94edf1..23ab8fc 100644 --- a/src/Encryption.cs +++ b/src/Encryption.cs @@ -162,6 +162,7 @@ namespace WTelegram session.AuthKeyID = BinaryPrimitives.ReadInt64LittleEndian(authKeyHash.AsSpan(12)); 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(Int128 server_nonce, Int256 new_nonce) { diff --git a/src/Session.cs b/src/Session.cs index d09b99d..11bf28a 100644 --- a/src/Session.cs +++ b/src/Session.cs @@ -23,6 +23,7 @@ namespace WTelegram public long AuthKeyID; public byte[] AuthKey; // 2048-bit = 256 bytes public long UserId; + public long OldSalt; // still accepted for a further 1800 seconds public long Salt; public SortedList Salts; public int Seqno;