DtlsVerifier
Implements cookie generation/verification for a DTLS server as described in RFC 4347,
4.2.1. Denial of Service Countermeasures.
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Tls.Crypto;
using Org.BouncyCastle.Utilities;
using System.IO;
namespace Org.BouncyCastle.Tls
{
public class DtlsVerifier
{
private readonly TlsCrypto m_crypto;
private readonly byte[] m_macKey;
public DtlsVerifier(TlsCrypto crypto)
{
m_crypto = crypto;
m_macKey = SecureRandom.GetNextBytes(crypto.SecureRandom, 32);
}
public virtual DtlsRequest VerifyRequest(byte[] clientID, byte[] data, int dataOff, int dataLen, DatagramSender sender)
{
try {
int num = DtlsRecordLayer.ReceiveClientHelloRecord(data, dataOff, dataLen);
if (num < 0)
return null;
int num2 = num - 12;
if (num2 < 39)
return null;
int num3 = dataOff + 13;
MemoryStream memoryStream = DtlsReliableHandshake.ReceiveClientHelloMessage(data, num3, num);
if (memoryStream == null)
return null;
MemoryStream memoryStream2 = new MemoryStream(num2);
ClientHello clientHello = ClientHello.Parse(memoryStream, memoryStream2);
if (clientHello == null)
return null;
long recordSeq = TlsUtilities.ReadUint48(data, dataOff + 5);
byte[] cookie = clientHello.Cookie;
TlsMac tlsMac = m_crypto.CreateHmac(3);
tlsMac.SetKey(m_macKey, 0, m_macKey.Length);
tlsMac.Update(clientID, 0, clientID.Length);
memoryStream2.WriteTo(new TlsMacSink(tlsMac));
byte[] array = tlsMac.CalculateMac();
if (Arrays.FixedTimeEquals(array, cookie)) {
byte[] message = TlsUtilities.CopyOfRangeExact(data, num3, num3 + num);
return new DtlsRequest(recordSeq, message, clientHello);
}
DtlsReliableHandshake.SendHelloVerifyRequest(sender, recordSeq, array);
} catch (IOException) {
}
return null;
}
}
}