]> git.deb.at Git - rhonda/impostor.hazel.git/commitdiff
Add DTLS connection tests
authorMatthew Endsley <mendsley@gmail.com>
Tue, 2 Feb 2021 14:17:23 +0000 (06:17 -0800)
committerMatthew Endsley <mendsley@gmail.com>
Wed, 3 Feb 2021 09:32:57 +0000 (01:32 -0800)
Hazel.UnitTests/Dtls/ConnectionTests.cs [new file with mode: 0644]
Hazel.UnitTests/Hazel.UnitTests.csproj
Hazel.UnitTests/TestLogger.cs [new file with mode: 0644]
Hazel.UnitTests/Utils.cs
Hazel.UnitTests/packages.config [new file with mode: 0644]

diff --git a/Hazel.UnitTests/Dtls/ConnectionTests.cs b/Hazel.UnitTests/Dtls/ConnectionTests.cs
new file mode 100644 (file)
index 0000000..c6132fa
--- /dev/null
@@ -0,0 +1,135 @@
+using Hazel.Dtls;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Net;
+using System.Security.Cryptography;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
+
+namespace Hazel.UnitTests.Dtls
+{
+    [TestClass]
+    public class ConnectionTests
+    {
+        // Created with command line
+        // openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 100000 -out certificate.pem
+        const string TestCertificate =
+@"-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIUREHeZ36f23eBFQ1T3sJsBwHlSBEwDQYJKoZIhvcNAQEL
+BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
+GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAgFw0yMTAyMDIxNDE4MTBaGA8yMjk0
+MTExODE0MTgxMFowRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
+ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAMeHCR6Y6GFwH7ZnouxPLmqyCIJSCcfaGIuBU3k+
+MG2ZyXKhhhwclL8arx5x1cGmQFvPm5wXGKSiLFChj+bW5XN7xBAc5e9KVBCEabrr
+BY+X9r0a421Yjqn4F47IA2sQ6OygnttYIt0pgeEoQZhGvmc2ZfkELkptIHMavIsx
+B/R0tYgtquruWveIWMtr4O/AuPxkH750SO1OxwU8gj6QXSqskrxvhl9GBzAwBKaF
+W6t7yjR7eFqaGh7B55p4t5zrfYKCVgeyj5Yzr/xdvv3Q3H+0pex+JTMWrpsTaavq
+F2RZYbpTOofuiTwdWbAHnXW1aFSCCIrEdEs9X2FxB73V0fcCAwEAAaNTMFEwHQYD
+VR0OBBYEFETIkxnzoLXO2GcEgxTZgN8ypKowMB8GA1UdIwQYMBaAFETIkxnzoLXO
+2GcEgxTZgN8ypKowMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
+ACZl7WQec9xLTK0paBIkVUqZKucDCXQH0JC7z4ENbiRtQvWQm6xhAlDo8Tr8oUzj
+0/lft/g6wIo8dJ4jZ/iCSHnKz8qO80Gs/x5NISe9A/8Us1kq8y4nO40QW6xtQMH7
+j74pcfsGKDCaMFSQZnSc93a3ZMEuVPxdI5+qsvFIeC9xxRHUNo245eLqsJAe8s1c
+22Uoeu3gepozrPcIPAHADGr/CFp1HLkg9nFrTcatlNAF/N0PmLjmk/NIx/8h7n7Q
+5vapNkhcyCHsW8XB5ulKmF88QZ5BdvPmtSey0t/n8ru98615G5Wb4TS2MaprzYL3
+5ACeQOohFzevcQrEjjzkZAI=
+-----END CERTIFICATE-----
+";
+
+        const string TestPrivateKey =
+@"-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHhwkemOhhcB+2
+Z6LsTy5qsgiCUgnH2hiLgVN5PjBtmclyoYYcHJS/Gq8ecdXBpkBbz5ucFxikoixQ
+oY/m1uVze8QQHOXvSlQQhGm66wWPl/a9GuNtWI6p+BeOyANrEOjsoJ7bWCLdKYHh
+KEGYRr5nNmX5BC5KbSBzGryLMQf0dLWILarq7lr3iFjLa+DvwLj8ZB++dEjtTscF
+PII+kF0qrJK8b4ZfRgcwMASmhVure8o0e3hamhoeweeaeLec632CglYHso+WM6/8
+Xb790Nx/tKXsfiUzFq6bE2mr6hdkWWG6UzqH7ok8HVmwB511tWhUggiKxHRLPV9h
+cQe91dH3AgMBAAECggEAVq+jVajHJTYqgPwLu7E3EGHi8oOj/jESAuIgGwfa0HNF
+I0lr06DTOyfjt01ruiN5yKmtCKa8LSLMMAfRVlA9BexapUl42HqphTeSHARpuRYj
+u8sHzgTwjoXb7kuVuJlzKQMroU5sbzvOUr1Dql3p8TugGA0p82nv9DJEghC+TQT2
+GnCKhsnmwE7lb8h0z3G3yxdv3yZE0X6oFzllBGCb1O6cwsDeYsv+SyjnyUwJROGz
+/VkC1+B48ALm4DhA5QIUoaRhO8vaCa7dacQTkXw1hVdLcaS9slIdXxbb9GbJvI0c
+baqimIkE02VUUpmlOIKUpf1sRXy1aJFpDSvWsTNLaQKBgQD8TrcVUF7oOhX5hQer
+qfNDFPvCBiWlT+8tnJraauaD1sJLD5jpRWPDu5dZ96CSZVpD1E3GQm+x58CSUknG
+AUHyHfEHTpzx7elVeUj7gianmVu8r9mVKtErwPLDJ4AUhMJjEPX2Plmh9GgFck78
+s2gfIvxdI+znvkH9JwGBznTIRQKBgQDKcpO7wiu025ZyPWR2p+qUh2ZlvBBr/6rg
+GxbFE5VraIS6zSDVOcxjPLc1pVZ/vM2WGbda0eziLpvsyauTXMCueBiNBRWZb5E4
+NK81IgbgZc4VWN9xA00cfOzO4Bjt6990BdOxiQQ1XOz1cN8DFTfsA81qR+nIne58
+LhL0DmFLCwKBgCwsU92FbrhVwxcmdUtWu+JYwCMeFGU283cW3f2zjZwzc1zU5D6j
+CW5xX3Q+6Hv5Bq6tcthtNUT+gDad9ZCXE8ah+1r+Jngs4Rc33tE53i6lqOwGFaAK
+GQkCBP6p4cC15ZqWk5mDHQo/0h5x/uY7OtWIuIpOCeIg60i5FYh2bvfJAoGAPQ7t
+i7V2ZSfNaksl37upPn7P3WMpOMl1if3hkjLj3+84CPcRLf4urMeFIkLpocEZ6Gl9
+KYEjBtyz3mi8vMc+veAu12lvKEXD8MXDCi1nEYri6wFQ8s7iFPOAoKxqGGgJjv6q
+6GLAyC9ssGIIgO+HXEGRVLq3wfAQG5fx03X61h0CgYEAiz3f8xiIR6PC4Gn5iMWu
+wmIDk3EnxdaA+7AwN/M037jbmKfzLxA1n8jXYM+to4SJx8Fxo7MD5EDhq6UoYmPU
+tGe4Ite2N9jzxG7xQrVuIx6Cg4t+E7uZ1eZuhbQ1WpqCXPIFOtXuc4szXfwD4Z+p
+IsdbLCwHYD3GVgk/D7NVxyU=
+-----END PRIVATE KEY-----
+";
+        private static X509Certificate2 GetCertificateForServer()
+        {
+            RSA privateKey = Utils.DecodeRSAKeyFromPEM(TestPrivateKey);
+            X509Certificate2 privateCertificate = new X509Certificate2();
+            privateCertificate.Import(Utils.DecodePEM(TestCertificate));
+            privateCertificate.PrivateKey = privateKey;
+            return privateCertificate;
+        }
+
+        private static X509Certificate2Collection GetCertificateForClient()
+        {
+            X509Certificate2 publicCertificate = new X509Certificate2();
+            publicCertificate.Import(Utils.DecodePEM(TestCertificate));
+
+            X509Certificate2Collection clientCertificates = new X509Certificate2Collection();
+            clientCertificates.Add(publicCertificate);
+            return clientCertificates;
+        }
+
+        [TestMethod]
+        public void TestClientConnects()
+        {
+            IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 27510);
+
+            bool serverConnected = false;
+            bool serverDisconnected = false;
+            bool clientDisconnected = false;
+
+            Semaphore signal = new Semaphore(0, int.MaxValue);
+
+            using (DtlsConnectionListener listener = new DtlsConnectionListener(2, new IPEndPoint(IPAddress.Any, ep.Port), new TestLogger()))
+            using (DtlsUnityConnection connection = new DtlsUnityConnection(new TestLogger(), ep))
+            {
+                listener.SetCertificate(GetCertificateForServer());
+                connection.SetValidServerCertificates(GetCertificateForClient());
+
+                listener.NewConnection += (evt) =>
+                {
+                    serverConnected = true;
+                    signal.Release();
+                    evt.Connection.Disconnected += (o, et) => {
+                        serverDisconnected = true;
+                    };
+                };
+                connection.Disconnected += (o, evt) => {
+                    clientDisconnected = true;
+                    signal.Release();
+                };
+
+                listener.Start();
+                connection.Connect();
+
+                // wait for the client to connect
+                signal.WaitOne(10);
+
+                listener.Dispose();
+
+                // wait for the client to disconnect
+                signal.WaitOne(100);
+
+                Assert.IsTrue(serverConnected);
+                Assert.IsTrue(clientDisconnected);
+                Assert.IsFalse(serverDisconnected);
+            }
+        }
+    }
+}
index b62a95f2a8c1bdbd84908cf23360ae5622bfa729..89382a483a00dcb85a110c49d1a59a5219593163 100644 (file)
@@ -39,6 +39,9 @@
     <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="BouncyCastle.Crypto, Version=1.8.9.0, Culture=neutral, PublicKeyToken=0e99375e54769942">
+      <HintPath>..\packages\BouncyCastle.1.8.9\lib\BouncyCastle.Crypto.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
   </ItemGroup>
   <Choose>
     <Compile Include="Crypto\AesGcmTest.cs" />
     <Compile Include="Crypto\X25519Tests.cs" />
     <Compile Include="Dtls\AesGcmRecordProtectedTests.cs" />
+    <Compile Include="Dtls\ConnectionTests.cs" />
     <Compile Include="Dtls\X25519EcdheRsaSha256Tests.cs" />
     <Compile Include="MessageReaderTests.cs" />
     <Compile Include="StatisticsTests.cs" />
     <Compile Include="TestHelper.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TestLogger.cs" />
     <Compile Include="UdpConnectionTestHarness.cs" />
     <Compile Include="ThreadLimitedUdpConnectionTests.cs" />
     <Compile Include="UnityUdpConnectionTests.cs" />
@@ -81,6 +86,9 @@
       <Name>Hazel</Name>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
   <Choose>
     <When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
       <ItemGroup>
diff --git a/Hazel.UnitTests/TestLogger.cs b/Hazel.UnitTests/TestLogger.cs
new file mode 100644 (file)
index 0000000..6b2c570
--- /dev/null
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hazel.UnitTests
+{
+    public class TestLogger : ILogger
+    {
+        public void WriteError(string msg)
+        {
+            Console.WriteLine($"[ERROR] {msg}");
+        }
+
+        public void WriteInfo(string msg)
+        {
+            Console.WriteLine($"[INFO] {msg}");
+        }
+    }
+}
index c0ca08f36dcf10c59c5bce6418d7dbf4744c5066..988cb5874e1789f1c2577272ef9a0682be5b6f8b 100644 (file)
@@ -1,5 +1,13 @@
-using System.Linq;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.OpenSsl;
+using Org.BouncyCastle.Security;
+using System;
+using System.Collections.Generic;
+using System.Linq;
 using System.Text;
+using System.IO;
+using System.Security.Cryptography;
 
 namespace Hazel.UnitTests
 {
@@ -58,5 +66,32 @@ namespace Hazel.UnitTests
 
             return output;
         }
+
+        public static byte[] DecodePEM(string pemData)
+        {
+            List<byte> result = new List<byte>();
+
+            pemData = pemData.Replace("\r", "");
+            string[] lines = pemData.Split('\n');
+            foreach (string line in lines)
+            {
+                if (line.StartsWith("-----"))
+                {
+                    continue;
+                }
+
+                byte[] lineData = Convert.FromBase64String(line);
+                result.AddRange(lineData);
+            }
+
+            return result.ToArray();
+        }
+
+        public static RSA DecodeRSAKeyFromPEM(string pemData)
+        {
+            PemReader pemReader = new PemReader(new StringReader(pemData));
+            RsaPrivateCrtKeyParameters keyParameters = (RsaPrivateCrtKeyParameters)pemReader.ReadObject();
+            return DotNetUtilities.ToRSA(keyParameters);
+        }
     }
 }
diff --git a/Hazel.UnitTests/packages.config b/Hazel.UnitTests/packages.config
new file mode 100644 (file)
index 0000000..37a0a96
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="BouncyCastle" version="1.8.9" targetFramework="net45" />
+</packages>
\ No newline at end of file