--- /dev/null
+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);
+ }
+ }
+ }
+}
<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" />
<Name>Hazel</Name>
</ProjectReference>
</ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
<ItemGroup>
-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
{
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);
+ }
}
}