Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions TechnitiumLibrary.Net/Dns/DnsDatagram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1447,11 +1447,9 @@ public bool VerifySignedRequest(IReadOnlyDictionary<string, TsigKey> keys, out D
}

//Check time values
DateTime startTime = DateTime.UnixEpoch.AddSeconds(tsig.TimeSigned - tsig.Fudge);
DateTime endTime = DateTime.UnixEpoch.AddSeconds(tsig.TimeSigned + tsig.Fudge);
DateTime utcNow = DateTime.UtcNow;

if ((utcNow < startTime) || (utcNow > endTime))
if (!IsTsigTimeValid(tsig.TimeSigned, tsig.Fudge, utcNow))
{
unsignedRequest = null;

Expand All @@ -1474,6 +1472,18 @@ public bool VerifySignedRequest(IReadOnlyDictionary<string, TsigKey> keys, out D
return false;
}

// RFC 8945 Section 4.2 requires the Error field to be zero in TSIG requests.
// Check it after TSIG validation so malformed authenticated requests receive a signed FORMERR.
if (tsig.Error != DnsTsigError.NoError)
{
unsignedRequest = null;

errorResponse = new DnsDatagram(_ID, true, _OPCODE, _AA == 1, _TC == 1, _RD == 1, _RA == 1, _AD == 1, _CD == 1, DnsResponseCode.FormatError, _question);
errorResponse = errorResponse.SignResponse(this, keys);

return false;
}

//return
IReadOnlyList<DnsResourceRecord> additional;

Expand Down Expand Up @@ -1713,10 +1723,8 @@ public bool VerifySignedResponse(DnsDatagram signedRequest, TsigKey key, out Dns

//Check time values
DateTime utcNow = DateTime.UtcNow;
DateTime startTime = DateTime.UnixEpoch.AddSeconds(tsig.TimeSigned - tsig.Fudge);
DateTime endTime = DateTime.UnixEpoch.AddSeconds(tsig.TimeSigned + tsig.Fudge);

if ((utcNow < startTime) || (utcNow > endTime))
if (!IsTsigTimeValid(tsig.TimeSigned, tsig.Fudge, utcNow))
{
unsignedResponse = null;
requestFailed = false;
Expand Down Expand Up @@ -1825,10 +1833,7 @@ public bool VerifySignedResponse(DnsDatagram signedRequest, TsigKey key, out Dns
}

//Check time values
DateTime currentStartTime = DateTime.UnixEpoch.AddSeconds(currentTsig.TimeSigned - currentTsig.Fudge);
DateTime currentEndTime = DateTime.UnixEpoch.AddSeconds(currentTsig.TimeSigned + currentTsig.Fudge);

if ((utcNow < currentStartTime) || (utcNow > currentEndTime))
if (!IsTsigTimeValid(currentTsig.TimeSigned, currentTsig.Fudge, utcNow))
{
unsignedResponse = null;
requestFailed = false;
Expand Down Expand Up @@ -1913,6 +1918,12 @@ public bool VerifySignedResponse(DnsDatagram signedRequest, TsigKey key, out Dns

#region private

private static bool IsTsigTimeValid(ulong timeSigned, ushort fudge, DateTime utcNow)
{
// RFC 8945 Sections 5.2.3 and 5.4.3 require current time to be within Time Signed +/- Fudge.
return Math.Abs((utcNow - DateTime.UnixEpoch).TotalSeconds - timeSigned) <= fudge;
}

private byte[] ComputeTsigRequestMac(string keyName, string algorithmName, ulong timeSigned, ushort fudge, DnsTsigError error, byte[] otherData, string sharedSecret, int truncationLength)
{
using (MemoryStream mS = new MemoryStream(256))
Expand Down