Skip to content

Commit 76b5480

Browse files
committed
Replace sequence number validation with manual
1 parent f8f2a55 commit 76b5480

File tree

3 files changed

+94
-3
lines changed

3 files changed

+94
-3
lines changed

Kerberos.NET/Crypto/DecryptedKrbApRep.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,52 @@ public override void Validate(ValidationActions validation)
6161
nameof(this.CuSec)
6262
);
6363
}
64+
65+
if (validation.HasFlag(ValidationActions.SequenceNumberEquals))
66+
{
67+
this.ValidateSequenceNumberEquals();
68+
}
69+
70+
if (validation.HasFlag(ValidationActions.SequenceNumberGreaterThan))
71+
{
72+
this.ValidateSequenceNumberGreaterThan();
73+
}
74+
}
75+
76+
private void ValidateSequenceNumberGreaterThan()
77+
{
78+
if (this.SequenceNumber >= this.Response.SequenceNumber)
79+
{
80+
throw new KerberosValidationException(
81+
$"SequenceNumber is not incrementing. Sent: {this.SequenceNumber}; Received: {this.Response.SequenceNumber}",
82+
nameof(this.SequenceNumber)
83+
);
84+
}
85+
else if (this.SequenceNumber is not null && this.Response.SequenceNumber is null)
86+
{
87+
throw new KerberosValidationException(
88+
$"Response SequenceNumber is null. Sent: {this.SequenceNumber}; Received: {this.Response.SequenceNumber}",
89+
nameof(this.SequenceNumber)
90+
);
91+
}
92+
else if (this.SequenceNumber is null && this.Response.SequenceNumber is null)
93+
{
94+
throw new KerberosValidationException(
95+
$"Both SequenceNumber and response SequenceNumber are null and not incrementing. Sent: {this.SequenceNumber}; Received: {this.Response.SequenceNumber}",
96+
nameof(this.SequenceNumber)
97+
);
98+
}
99+
}
100+
101+
private void ValidateSequenceNumberEquals()
102+
{
103+
if (this.SequenceNumber != this.Response.SequenceNumber)
104+
{
105+
throw new KerberosValidationException(
106+
$"SequenceNumber does not match. Sent: {this.SequenceNumber}; Received: {this.Response.SequenceNumber}",
107+
nameof(this.SequenceNumber)
108+
);
109+
}
64110
}
65111
}
66112
}

Kerberos.NET/ValidationAction.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// -----------------------------------------------------------------------
1+
// -----------------------------------------------------------------------
22
// Licensed to The .NET Foundation under one or more agreements.
33
// The .NET Foundation licenses this file to you under the MIT license.
44
// -----------------------------------------------------------------------
@@ -58,9 +58,21 @@ public enum ValidationActions
5858
/// </summary>
5959
RenewTill = 1 << 7,
6060

61+
/// <summary>
62+
/// Validates that the caller wants to check if the sequence number equals the expected value.
63+
/// Incompatible with `SequenceNumberGreaterThan`.
64+
/// </summary>
65+
SequenceNumberEquals = 1 << 8,
66+
67+
/// <summary>
68+
/// Validates that the caller wants to check if the sequence number is greater than the expected value.
69+
/// Incompatible with `SequenceNumberEquals`.
70+
/// </summary>
71+
SequenceNumberGreaterThan = 1 << 9,
72+
6173
/// <summary>
6274
/// Indicates all validation actions must be invoked.
6375
/// </summary>
6476
All = ClientPrincipalIdentifier | Realm | TokenWindow | StartTime | EndTime | Replay | Pac | RenewTill
6577
}
66-
}
78+
}

Tests/Tests.Kerberos.NET/KrbApReq/ValidatorTests.cs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ public void DecryptedKrbApReq_Validate_NotBefore()
231231
decrypted.Validate(ValidationActions.All);
232232
}
233233

234-
private static DecryptedKrbApRep CreateResponseMessage(DateTimeOffset ctime, int cusec, int sequence, KerberosKey sessionKey)
234+
private static DecryptedKrbApRep CreateResponseMessage(DateTimeOffset ctime, int cusec, int? sequence, KerberosKey sessionKey)
235235
{
236236
var apRepPart = new KrbEncApRepPart
237237
{
@@ -384,5 +384,38 @@ public void DecryptedKrbApRep_Validate_CuSec()
384384

385385
decrypted.Validate(ValidationActions.All);
386386
}
387+
388+
[TestMethod]
389+
[DataRow(ValidationActions.SequenceNumberEquals, 123, 123, true)]
390+
[DataRow(ValidationActions.SequenceNumberEquals, 123, 124, false)]
391+
[DataRow(ValidationActions.SequenceNumberEquals, null, 123, false)]
392+
[DataRow(ValidationActions.SequenceNumberEquals, 123, null, false)]
393+
[DataRow(ValidationActions.SequenceNumberEquals, null, null, true)]
394+
[DataRow(ValidationActions.SequenceNumberGreaterThan, 123, 124, true)]
395+
[DataRow(ValidationActions.SequenceNumberGreaterThan, 123, 123, false)]
396+
[DataRow(ValidationActions.SequenceNumberGreaterThan, null, 124, true)]
397+
[DataRow(ValidationActions.SequenceNumberGreaterThan, 123, null, false)]
398+
[DataRow(ValidationActions.SequenceNumberGreaterThan, null, null, false)]
399+
public void DecryptedKrbApRep_Validate_SequenceNumber(ValidationActions validation, int? current, int? resp, bool expectedSuccess)
400+
{
401+
var now = DateTimeOffset.UtcNow;
402+
403+
var sessionKey = KrbEncryptionKey.Generate(EncryptionType.AES128_CTS_HMAC_SHA1_96);
404+
405+
var decrypted = CreateResponseMessage(now, 111, resp, sessionKey.AsKey());
406+
407+
decrypted.SequenceNumber = current;
408+
decrypted.CTime = now;
409+
decrypted.CuSec = 111;
410+
411+
if (!expectedSuccess)
412+
{
413+
Assert.ThrowsException<KerberosValidationException>(() => decrypted.Validate(ValidationActions.All | validation));
414+
}
415+
else
416+
{
417+
decrypted.Validate(ValidationActions.All | validation);
418+
}
419+
}
387420
}
388421
}

0 commit comments

Comments
 (0)