Skip to content

Commit a50837b

Browse files
committed
[Core] Fix the EcdhProvider would not provide 32 bytes sharekey
1 parent c25747c commit a50837b

8 files changed

Lines changed: 526 additions & 38 deletions

File tree

Lagrange.Core.Test/Cryptography/EcdhTest.cs

Lines changed: 477 additions & 21 deletions
Large diffs are not rendered by default.

Lagrange.Core/Common/Entity/BotSsoPacket.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public class BotSsoPacket
1010

1111
public int RetCode { get; }
1212

13-
public int Sequence { get; }
13+
public int Sequence { get; internal set; }
1414

1515
/// <summary>
1616
/// Constructs a new SSO packet with the specified command and data.

Lagrange.Core/Common/Interface/BotExt.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ public static bool SubmitCaptcha(this BotContext context, string ticket, string
2323
public static bool SubmitSMSCode(this BotContext context, string code) =>
2424
context.EventContext.GetLogic<WtExchangeLogic>().SubmitSMSCode(code);
2525

26-
public static ValueTask<BotSsoPacket> SendPacket(this BotContext context, BotSsoPacket packet)
27-
=> context.EventContext.GetLogic<OperationLogic>().SendPacket(packet);
26+
public static ValueTask<BotSsoPacket> SendPacket(this BotContext context, BotSsoPacket packet, RequestType requestType = RequestType.D2Auth, EncryptType encryptType = EncryptType.EncryptD2Key)
27+
=> context.EventContext.GetLogic<OperationLogic>().SendPacket(packet, requestType, encryptType);
2828
}

Lagrange.Core/Internal/Context/PacketContext.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,17 @@ public ValueTask<BotSsoPacket> SendPacket(BotSsoPacket packet, ServiceAttribute
6464
}
6565
case RequestType.Simple:
6666
{
67-
var sso = _ssoPacker.BuildProtocol13(packet);
68-
frame = _servicePacker.BuildProtocol13(packet, sso, options);
67+
if (SignProvider.IsWhiteListCommand(packet.Command))
68+
{
69+
var secInfo = await SignProvider.GetSecSign(_keystore.Uin, packet.Command, packet.Sequence, packet.Data);
70+
var sso = _ssoPacker.BuildProtocol13(packet, secInfo);
71+
frame = _servicePacker.BuildProtocol13(packet, sso, options);
72+
}
73+
else
74+
{
75+
var sso = _ssoPacker.BuildProtocol13(packet, null);
76+
frame = _servicePacker.BuildProtocol13(packet, sso, options);
77+
}
6978
break;
7079
}
7180
default:

Lagrange.Core/Internal/Context/ServiceContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public ValueTask<ProtocolEvent> Resolve(BotSsoPacket ssoPacket)
7676
return (new BotSsoPacket(attr.Command, await service.Build(@event, _context), GetNewSequence()), attr);
7777
}
7878

79-
private int GetNewSequence()
79+
public int GetNewSequence()
8080
{
8181
Interlocked.CompareExchange(ref _sequence, 5000000, 9900000);
8282
return Interlocked.Increment(ref _sequence);

Lagrange.Core/Internal/Logic/OperationLogic.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ internal class OperationLogic(BotContext context) : ILogic
2323

2424
public async Task<Dictionary<string, string>> FetchCookies(List<string> domains) => (await context.EventContext.SendEvent<FetchCookiesEventResp>(new FetchCookiesEventReq(domains))).Cookies;
2525

26-
public ValueTask<BotSsoPacket> SendPacket(BotSsoPacket packet)
26+
public ValueTask<BotSsoPacket> SendPacket(BotSsoPacket packet, RequestType requestType, EncryptType encryptType)
2727
{
28-
return context.PacketContext.SendPacket(packet, new ServiceAttribute(packet.Command));
28+
int sequence = packet.Sequence != 0 ? packet.Sequence : context.ServiceContext.GetNewSequence();
29+
packet.Sequence = sequence;
30+
return context.PacketContext.SendPacket(packet, new ServiceAttribute(packet.Command, requestType, encryptType));
2931
}
3032

3133
public async Task<(string, uint)> FetchClientKey()

Lagrange.Core/Internal/Packets/Struct/SsoPacker.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ public BinaryPacket BuildProtocol12(BotSsoPacket sso, SsoSecureInfo? secInfo)
3939
return result;
4040
}
4141

42-
public BinaryPacket BuildProtocol13(BotSsoPacket sso)
42+
public BinaryPacket BuildProtocol13(BotSsoPacket sso, SsoSecureInfo? secInfo)
4343
{
4444
var head = new BinaryPacket(stackalloc byte[0x200]);
4545

4646
head.Write(sso.Command, Prefix.Int32 | Prefix.WithPrefix); // command
4747
head.Write(ReadOnlySpan<byte>.Empty, Prefix.Int32 | Prefix.WithPrefix); // message_cookies
48-
WriteSsoReservedField(ref head, null);
48+
WriteSsoReservedField(ref head, secInfo);
4949

5050
var headSpan = head.CreateReadOnlySpan();
5151
var result = new BinaryPacket(headSpan.Length + sso.Data.Length + 2 * 4); // 2 * 4 for the length of the payload

Lagrange.Core/Utility/Cryptography/EcdhProvider.cs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,22 @@ public byte[] PackPublic(bool compress)
4343
if (compress)
4444
{
4545
var result = new byte[Curve.Size + 1];
46-
46+
4747
result[0] = (byte) (Public.Y.IsEven ^ Public.Y.Sign < 0 ? 0x02 : 0x03);
48-
Public.X.TryWriteBytes(result.AsSpan()[1..], out _, true, true);
49-
48+
var xBytes = ToFixedBytes(Public.X, Curve.Size);
49+
xBytes.CopyTo(result, 1);
50+
5051
return result;
5152
}
5253
else
5354
{
5455
var result = new byte[Curve.Size * 2 + 1];
55-
56+
5657
result[0] = 0x04;
57-
Public.X.TryWriteBytes(result.AsSpan()[1..], out _, true, true);
58-
Public.Y.TryWriteBytes(result.AsSpan()[(Curve.Size + 1)..], out _, true, true);
58+
var xBytes = ToFixedBytes(Public.X, Curve.Size);
59+
var yBytes = ToFixedBytes(Public.Y, Curve.Size);
60+
xBytes.CopyTo(result, 1);
61+
yBytes.CopyTo(result, Curve.Size + 1);
5962

6063
return result;
6164
}
@@ -72,7 +75,7 @@ public byte[] PackSecret()
7275

7376
private byte[] PackShared(EllipticPoint ecShared, bool isHash)
7477
{
75-
var x = ecShared.X.ToByteArray(true, true);
78+
var x = ToFixedBytes(ecShared.X, Curve.Size);
7679
return !isHash ? x : MD5.HashData(x[..Curve.PackSize]);
7780
}
7881

@@ -202,6 +205,24 @@ private static BigInteger Mod(BigInteger a, BigInteger b)
202205
if (result < 0) result += b;
203206
return result;
204207
}
208+
209+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
210+
private static byte[] ToFixedBytes(BigInteger value, int size)
211+
{
212+
var bytes = value.ToByteArray(true, true);
213+
if (bytes.Length == size) return bytes;
214+
215+
var result = new byte[size];
216+
if (bytes.Length < size)
217+
{
218+
bytes.CopyTo(result, size - bytes.Length);
219+
}
220+
else
221+
{
222+
Array.Copy(bytes, bytes.Length - size, result, 0, size);
223+
}
224+
return result;
225+
}
205226
}
206227

207228
internal readonly struct EllipticCurve

0 commit comments

Comments
 (0)