aboutsummaryrefslogtreecommitdiff
path: root/Tools/Hazel-Networking/Hazel.UnitTests/Dtls/AesGcmRecordProtectedTests.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/Hazel-Networking/Hazel.UnitTests/Dtls/AesGcmRecordProtectedTests.cs')
-rw-r--r--Tools/Hazel-Networking/Hazel.UnitTests/Dtls/AesGcmRecordProtectedTests.cs205
1 files changed, 205 insertions, 0 deletions
diff --git a/Tools/Hazel-Networking/Hazel.UnitTests/Dtls/AesGcmRecordProtectedTests.cs b/Tools/Hazel-Networking/Hazel.UnitTests/Dtls/AesGcmRecordProtectedTests.cs
new file mode 100644
index 0000000..8e71f2d
--- /dev/null
+++ b/Tools/Hazel-Networking/Hazel.UnitTests/Dtls/AesGcmRecordProtectedTests.cs
@@ -0,0 +1,205 @@
+using Hazel.Dtls;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace Hazel.UnitTests.Dtls
+{
+ [TestClass]
+ public class AesGcmRecordProtectedTests
+ {
+ private readonly ByteSpan masterSecret;
+ private readonly ByteSpan serverRandom;
+ private readonly ByteSpan clientRandom;
+
+ private const string TestMessage = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
+
+ public AesGcmRecordProtectedTests()
+ {
+ this.masterSecret = new byte[48];
+ this.serverRandom = new byte[32];
+ this.clientRandom = new byte[32];
+
+ using (RandomNumberGenerator random = RandomNumberGenerator.Create())
+ {
+ random.GetBytes(this.masterSecret.GetUnderlyingArray());
+ random.GetBytes(this.serverRandom.GetUnderlyingArray());
+ random.GetBytes(this.clientRandom.GetUnderlyingArray());
+ }
+ }
+
+ [TestMethod]
+ public void ServerCanEncryptAndDecryptData()
+ {
+ using (Aes128GcmRecordProtection recordProtection = new Aes128GcmRecordProtection(this.masterSecret, this.serverRandom, this.clientRandom))
+ {
+ byte[] messageAsBytes = Encoding.UTF8.GetBytes(TestMessage);
+
+ Record record = new Record();
+ record.ContentType = ContentType.ApplicationData;
+ record.ProtocolVersion = ProtocolVersion.DTLS1_2;
+ record.Epoch = 1;
+ record.SequenceNumber = 124;
+ record.Length = (ushort)recordProtection.GetEncryptedSize(messageAsBytes.Length);
+
+ ByteSpan encrypted = new byte[record.Length];
+ recordProtection.EncryptServerPlaintext(encrypted, messageAsBytes, ref record);
+
+ ByteSpan plaintext = new byte[recordProtection.GetDecryptedSize(encrypted.Length)];
+ bool couldDecrypt = recordProtection.DecryptCiphertextFromServer(plaintext, encrypted, ref record);
+ Assert.IsTrue(couldDecrypt);
+ Assert.AreEqual(messageAsBytes.Length, plaintext.Length);
+ Assert.AreEqual(TestMessage, Encoding.UTF8.GetString(plaintext.GetUnderlyingArray(), plaintext.Offset, plaintext.Length));
+ }
+ }
+
+ [TestMethod]
+ public void ClientCanEncryptAndDecryptData()
+ {
+ using (Aes128GcmRecordProtection recordProtection = new Aes128GcmRecordProtection(this.masterSecret, this.serverRandom, this.clientRandom))
+ {
+ byte[] messageAsBytes = Encoding.UTF8.GetBytes(TestMessage);
+
+ Record record = new Record();
+ record.ContentType = ContentType.ApplicationData;
+ record.ProtocolVersion = ProtocolVersion.DTLS1_2;
+ record.Epoch = 1;
+ record.SequenceNumber = 124;
+ record.Length = (ushort)recordProtection.GetEncryptedSize(messageAsBytes.Length);
+
+ ByteSpan encrypted = new byte[record.Length];
+ recordProtection.EncryptClientPlaintext(encrypted, messageAsBytes, ref record);
+
+ ByteSpan plaintext = new byte[recordProtection.GetDecryptedSize(encrypted.Length)];
+ bool couldDecrypt = recordProtection.DecryptCiphertextFromClient(plaintext, encrypted, ref record);
+ Assert.IsTrue(couldDecrypt);
+ Assert.AreEqual(messageAsBytes.Length, plaintext.Length);
+ Assert.AreEqual(TestMessage, Encoding.UTF8.GetString(plaintext.GetUnderlyingArray(), plaintext.Offset, plaintext.Length));
+ }
+ }
+
+ [TestMethod]
+ public void ServerDecryptionFailsWhenRecordModified()
+ {
+ using (Aes128GcmRecordProtection recordProtection = new Aes128GcmRecordProtection(this.masterSecret, this.serverRandom, this.clientRandom))
+ {
+ byte[] messageAsBytes = Encoding.UTF8.GetBytes(TestMessage);
+
+ Record originalRecord = new Record();
+ originalRecord.ContentType = ContentType.ApplicationData;
+ originalRecord.ProtocolVersion = ProtocolVersion.DTLS1_2;
+ originalRecord.Epoch = 1;
+ originalRecord.SequenceNumber = 124;
+ originalRecord.Length = (ushort)recordProtection.GetEncryptedSize(messageAsBytes.Length);
+
+ ByteSpan encrypted = new byte[originalRecord.Length];
+ recordProtection.EncryptServerPlaintext(encrypted, messageAsBytes, ref originalRecord);
+
+ ByteSpan plaintext = new byte[recordProtection.GetDecryptedSize(encrypted.Length)];
+
+ Record record = originalRecord;
+ record.ContentType = ContentType.Handshake;
+ bool couldDecrypt = recordProtection.DecryptCiphertextFromServer(plaintext, encrypted, ref record);
+ Assert.IsFalse(couldDecrypt);
+
+ record = originalRecord;
+ record.Epoch++;
+ couldDecrypt = recordProtection.DecryptCiphertextFromServer(plaintext, encrypted, ref record);
+ Assert.IsFalse(couldDecrypt);
+
+ record = originalRecord;
+ record.SequenceNumber++;
+ couldDecrypt = recordProtection.DecryptCiphertextFromServer(plaintext, encrypted, ref record);
+ Assert.IsFalse(couldDecrypt);
+ }
+ }
+
+ [TestMethod]
+ public void ClientDecryptionFailsWhenRecordModified()
+ {
+ using (Aes128GcmRecordProtection recordProtection = new Aes128GcmRecordProtection(this.masterSecret, this.serverRandom, this.clientRandom))
+ {
+ byte[] messageAsBytes = Encoding.UTF8.GetBytes(TestMessage);
+
+ Record originalRecord = new Record();
+ originalRecord.ContentType = ContentType.ApplicationData;
+ originalRecord.ProtocolVersion = ProtocolVersion.DTLS1_2;
+ originalRecord.Epoch = 1;
+ originalRecord.SequenceNumber = 124;
+ originalRecord.Length = (ushort)recordProtection.GetEncryptedSize(messageAsBytes.Length);
+
+ ByteSpan encrypted = new byte[originalRecord.Length];
+ recordProtection.EncryptClientPlaintext(encrypted, messageAsBytes, ref originalRecord);
+
+ ByteSpan plaintext = new byte[recordProtection.GetDecryptedSize(encrypted.Length)];
+
+ Record record = originalRecord;
+ record.ContentType = ContentType.Handshake;
+ bool couldDecrypt = recordProtection.DecryptCiphertextFromClient(plaintext, encrypted, ref record);
+ Assert.IsFalse(couldDecrypt);
+
+ record = originalRecord;
+ record.Epoch++;
+ couldDecrypt = recordProtection.DecryptCiphertextFromClient(plaintext, encrypted, ref record);
+ Assert.IsFalse(couldDecrypt);
+
+ record = originalRecord;
+ record.SequenceNumber++;
+ couldDecrypt = recordProtection.DecryptCiphertextFromClient(plaintext, encrypted, ref record);
+ Assert.IsFalse(couldDecrypt);
+ }
+ }
+
+ [TestMethod]
+ public void ServerEncryptionCanoverlap()
+ {
+ using (Aes128GcmRecordProtection recordProtection = new Aes128GcmRecordProtection(this.masterSecret, this.serverRandom, this.clientRandom))
+ {
+ ByteSpan messageAsBytes = Encoding.UTF8.GetBytes(TestMessage);
+
+ Record record = new Record();
+ record.ContentType = ContentType.ApplicationData;
+ record.ProtocolVersion = ProtocolVersion.DTLS1_2;
+ record.Epoch = 1;
+ record.SequenceNumber = 124;
+ record.Length = (ushort)recordProtection.GetEncryptedSize(messageAsBytes.Length);
+
+ ByteSpan encrypted = new byte[record.Length];
+ messageAsBytes.CopyTo(encrypted);
+ recordProtection.EncryptServerPlaintext(encrypted, encrypted.Slice(0, messageAsBytes.Length), ref record);
+
+ ByteSpan plaintext = encrypted.Slice(0, recordProtection.GetDecryptedSize(record.Length));
+ bool couldDecrypt = recordProtection.DecryptCiphertextFromServer(plaintext, encrypted, ref record);
+ Assert.IsTrue(couldDecrypt);
+ Assert.AreEqual(messageAsBytes.Length, plaintext.Length);
+ Assert.AreEqual(TestMessage, Encoding.UTF8.GetString(plaintext.GetUnderlyingArray(), plaintext.Offset, plaintext.Length));
+ }
+ }
+
+ [TestMethod]
+ public void ClientEncryptionCanoverlap()
+ {
+ using (Aes128GcmRecordProtection recordProtection = new Aes128GcmRecordProtection(this.masterSecret, this.serverRandom, this.clientRandom))
+ {
+ ByteSpan messageAsBytes = Encoding.UTF8.GetBytes(TestMessage);
+
+ Record record = new Record();
+ record.ContentType = ContentType.ApplicationData;
+ record.ProtocolVersion = ProtocolVersion.DTLS1_2;
+ record.Epoch = 1;
+ record.SequenceNumber = 124;
+ record.Length = (ushort)recordProtection.GetEncryptedSize(messageAsBytes.Length);
+
+ ByteSpan encrypted = new byte[record.Length];
+ messageAsBytes.CopyTo(encrypted);
+ recordProtection.EncryptClientPlaintext(encrypted, encrypted.Slice(0, messageAsBytes.Length), ref record);
+
+ ByteSpan plaintext = encrypted.Slice(0, recordProtection.GetDecryptedSize(record.Length));
+ bool couldDecrypt = recordProtection.DecryptCiphertextFromClient(plaintext, encrypted, ref record);
+ Assert.IsTrue(couldDecrypt);
+ Assert.AreEqual(messageAsBytes.Length, plaintext.Length);
+ Assert.AreEqual(TestMessage, Encoding.UTF8.GetString(plaintext.GetUnderlyingArray(), plaintext.Offset, plaintext.Length));
+ }
+ }
+ }
+}