Fix #216: The old salt should be accepted for a further 1800 seconds

This commit is contained in:
Wizou 2023-12-18 00:01:07 +01:00
parent cce7a64cd9
commit e6fa972295
3 changed files with 7 additions and 2 deletions

View file

@ -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;

View file

@ -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)
{

View file

@ -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<DateTime, long> Salts;
public int Seqno;