diff options
Diffstat (limited to 'crypto/test')
53 files changed, 3376 insertions, 286 deletions
diff --git a/crypto/test/UnitTests.csproj b/crypto/test/UnitTests.csproj index 59cff41e1..3fd7154d9 100644 --- a/crypto/test/UnitTests.csproj +++ b/crypto/test/UnitTests.csproj @@ -256,13 +256,37 @@ <Compile Include="src\crypto\test\VMPCMacTest.cs" /> <Compile Include="src\crypto\test\VMPCTest.cs" /> <Compile Include="src\crypto\test\WhirlpoolDigestTest.cs" /> + <Compile Include="src\crypto\test\X931SignerTest.cs" /> <Compile Include="src\crypto\test\XSalsa20Test.cs" /> <Compile Include="src\crypto\test\XTEATest.cs" /> + <Compile Include="src\crypto\tls\test\DtlsProtocolTest.cs" /> + <Compile Include="src\crypto\tls\test\DtlsTestCase.cs" /> + <Compile Include="src\crypto\tls\test\DtlsTestSuite.cs" /> + <Compile Include="src\crypto\tls\test\LoggingDatagramTransport.cs" /> + <Compile Include="src\crypto\tls\test\MockDatagramAssociation.cs" /> + <Compile Include="src\crypto\tls\test\MockDtlsClient.cs" /> + <Compile Include="src\crypto\tls\test\MockDtlsServer.cs" /> + <Compile Include="src\crypto\tls\test\MockPskTlsClient.cs" /> + <Compile Include="src\crypto\tls\test\MockPskTlsServer.cs" /> + <Compile Include="src\crypto\tls\test\MockSrpTlsClient.cs" /> + <Compile Include="src\crypto\tls\test\MockSrpTlsServer.cs" /> <Compile Include="src\crypto\tls\test\MockTlsClient.cs" /> <Compile Include="src\crypto\tls\test\MockTlsServer.cs" /> + <Compile Include="src\crypto\tls\test\NetworkStream.cs" /> + <Compile Include="src\crypto\tls\test\PipedStream.cs" /> + <Compile Include="src\crypto\tls\test\PskTlsClientTest.cs" /> <Compile Include="src\crypto\tls\test\TlsClientTest.cs" /> + <Compile Include="src\crypto\tls\test\TlsProtocolTest.cs" /> + <Compile Include="src\crypto\tls\test\TlsPskProtocolTest.cs" /> <Compile Include="src\crypto\tls\test\TlsServerTest.cs" /> + <Compile Include="src\crypto\tls\test\TlsSrpProtocolTest.cs" /> + <Compile Include="src\crypto\tls\test\TlsTestCase.cs" /> + <Compile Include="src\crypto\tls\test\TlsTestClientImpl.cs" /> + <Compile Include="src\crypto\tls\test\TlsTestConfig.cs" /> + <Compile Include="src\crypto\tls\test\TlsTestServerImpl.cs" /> + <Compile Include="src\crypto\tls\test\TlsTestSuite.cs" /> <Compile Include="src\crypto\tls\test\TlsTestUtilities.cs" /> + <Compile Include="src\crypto\tls\test\UnreliableDatagramTransport.cs" /> <Compile Include="src\math\ec\test\AllTests.cs" /> <Compile Include="src\math\ec\test\ECAlgorithmsTest.cs" /> <Compile Include="src\math\ec\test\ECPointPerformanceTest.cs" /> @@ -1199,9 +1223,17 @@ <EmbeddedResource Include="data\tls\server.tmpl" /> <EmbeddedResource Include="data\tls\x509-ca-key.pem" /> <EmbeddedResource Include="data\tls\x509-ca.pem" /> + <EmbeddedResource Include="data\tls\x509-client-dsa.pem" /> + <EmbeddedResource Include="data\tls\x509-client-ecdsa.pem" /> <EmbeddedResource Include="data\tls\x509-client-key.pem" /> + <EmbeddedResource Include="data\tls\x509-client-key-dsa.pem" /> + <EmbeddedResource Include="data\tls\x509-client-key-ecdsa.pem" /> <EmbeddedResource Include="data\tls\x509-client.pem" /> + <EmbeddedResource Include="data\tls\x509-server-dsa.pem" /> + <EmbeddedResource Include="data\tls\x509-server-ecdsa.pem" /> <EmbeddedResource Include="data\tls\x509-server-key.pem" /> + <EmbeddedResource Include="data\tls\x509-server-key-dsa.pem" /> + <EmbeddedResource Include="data\tls\x509-server-key-ecdsa.pem" /> <EmbeddedResource Include="data\tls\x509-server.pem" /> <EmbeddedResource Include="data\tls\keystores\client_store.dsa" /> <EmbeddedResource Include="data\tls\keystores\client_store.rsa" /> diff --git a/crypto/test/data/tls/x509-client-dsa.pem b/crypto/test/data/tls/x509-client-dsa.pem new file mode 100644 index 000000000..91d9e4415 --- /dev/null +++ b/crypto/test/data/tls/x509-client-dsa.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFmzCCBFOgAwIBAgIMVOBtHi6d3lDIPyoMMA0GCSqGSIb3DQEBCwUAMCMxITAf +BgNVBAMTGEJvdW5jeUNhc3RsZSBUTFMgVGVzdCBDQTAiGA8yMDE1MDIxNTA5NTU0 +MloYDzIwMzUwMjEwMDk1NTQyWjAjMSEwHwYDVQQDExhCb3VuY3lDYXN0bGUgVGVz +dCBDbGllbnQwggNHMIICOgYHKoZIzjgEATCCAi0CggEBAPvZZVsYbqUzF5Aq5JCU +GJtg9+Hgrab/2F8vnEKsYKWtKFY4BCalIbhbZ/e4VPAEV1SlV/GgmtkPVrOutThq +03j/eo98t82vismks6SMupNoyOiPqDZ+HyNEZFIQV9Ur/1D/tPBQGrD7Fbh5JOmK +QPCoo46t9Xclfm+8u8bUIhFQV4LIkug5YBm2J8wy5FeaRYno1+4Hp543oD6SkOtF +aJCp05nfiNRtaZy/LXr22UnSggG9M/zug+u3Bi2R70TI5FJq7TwYHfAlbesbLBjH +QHvE95WlFxK1YovmziBLfew5RClZ3kgj7f3SL/3WeRy2ittQaObwV27ZNj4enYAD +qkkCIQDsN/jM9mS5UDmPNRR6Wby2jvJQbHdm6yMqlFiIXVAECQKCAQEAzVrnDdM6 +kPTVALWJNYC279xIEMETimJGP39o3YXMJFlyoEzFYamJPneYlYpY4jGfuetC+jFn +HouDivtjdf/vAc+og4jaro4NcaDCjzPZBTQuvb0cFhlSbVZsit1IMv/sztJUdPcd +QKnGP+NfiChBDh8LLskvuVefEia0Ix/xwdK764zVn9oxiP5E2sKMMYnnFoVykbKU +W43sOONe+P2zOF3VTIOUngszcNDKJsXrFKZ+MtE9FvKduaXBmd0y9Pat7jFCodry +127mBeIZOKb9h3YMZCf7tQBFpX6o8JX4Ltw9hVRIsspgarli3K18WmOR+6pvAzJx +IxxiYDbo1PHMAgOCAQUAAoIBAGPk3p3hPR51sTwf2LwDrZ5Fh9tLzFoSh6ojjiR/ +FJsqwbrEEPYi4vozJOBao17qfZayMArcq7QB5eUzBaeeggvyYgYPUIUh8kBZqeLp +WtWYBXwDqNQiRSAqX0nl35SZEnyyou4kidHFW4SWSbTQw9pkM1gtP2Q7pkxabdjt +fQTJsilslKFhoV/zWYsa72YJ1GilnDLwPanaBDdpnX84W+TDS2Gy2wb0o15etOTU +Ly9EoHisZZfdwdIoAd0pJbjSHAJnudB+skL2VfPwfwxQDOTV7gh6XIe5h5bLKR3x +ruLjNx1ppcTkjKmUruTp7V+/sH9EAS8B9epiNDGwL0s8gX6jdjB0MAwGA1UdEwEB +/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDwYDVR0PAQH/BAUDAweAADAdBgNV +HQ4EFgQUGvXFed+UN0C5+YrVvcR+7cn9U6swHwYDVR0jBBgwFoAU9mOvr6Pi7+4O +5bKxRihqeCkyHukwDQYJKoZIhvcNAQELBQADggExAChl15lXRB43Oh+qIeibolYt +OBCHlUQcQcFzqK556TKNQfhWoRv1ovxbxgPokogfnLfxKdmHrb4E+aF0syxNpXGn +gBY2G7uyuKjoJnMNsxdTiS6jzps+LlgwHMYsFac0vcJATVz1U8hoR90B4pwkNkXv +ErVXj4WvHqB5a4gsqPpAslZvhxOgWLvjA+1V4HohspnMVTup3zG6frdmwLWZ+FPI +LyrEaUaWiilFl83RWuVlExhxGyfLF8u/06OJYHCUNtHT4UQavFzQMz5UwruGor7x +n8QEE84SXaQxIyWO5T2vnlxZ0+fw/0GXyJS0F0WvJ5WkK+s+y6nXZ8Hq2fDecDWn +1nw44LpnwGb//010RdtOeAHAQmGuuEf8rf1Xiw990hAYvTzM4cT9/l22vQPR3rg= +-----END CERTIFICATE----- diff --git a/crypto/test/data/tls/x509-client-ecdsa.pem b/crypto/test/data/tls/x509-client-ecdsa.pem new file mode 100644 index 000000000..fd8bc845b --- /dev/null +++ b/crypto/test/data/tls/x509-client-ecdsa.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICqzCCAWOgAwIBAgIMVOBhzQE9XhiRAUXpMA0GCSqGSIb3DQEBCwUAMCMxITAf +BgNVBAMTGEJvdW5jeUNhc3RsZSBUTFMgVGVzdCBDQTAiGA8yMDE1MDIxNTA5MDcy +NVoYDzIwMzUwMjEwMDkwNzI1WjAjMSEwHwYDVQQDExhCb3VuY3lDYXN0bGUgVGVz +dCBDbGllbnQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASWdahP6F9xwnD6eABg +2AwifyDDCw5jy5hGe+Lnvyjok/zdkw2n8lWCFdhInFC7mRcGS7aduF7dykv9C9oU +mY17o3YwdDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMCMA8GA1Ud +DwEB/wQFAwMHgAAwHQYDVR0OBBYEFAg1z6i+u89U0RQrH9ApFWIklZrpMB8GA1Ud +IwQYMBaAFPZjr6+j4u/uDuWysUYoangpMh7pMA0GCSqGSIb3DQEBCwUAA4IBMQCL +RJIeoOlVOcseShihLd3OU7NU3tGeLDnEcwPOAPYsDN1c7V/zROTD/0W0nhSVdRfB +AyxjjDjq3J/MTf1DrouEynoAU8SZL5OnxbceX74U2WsSaJU0PAaw9zTOaKoOuTET +EVs/OMx00XXhZcu+lPFAKT3YNJKO1Rm7Sy4vnY4jnsuRsk9+D6E3CmDSnKQC/g90 +/0djrDTYpL9Lyd5zzekZPpzX7YgNfmq2X04521+3ahfq4bBMC8GRdAuon2h2FwFX ++aH9cjHHDgxPt5pHkg3Uk+Cl6KhVb2ilS0uYd4XaMPXOUOUOxRpmQ3/7YhNgyyaL +IOP+fWkbOiFbUTDaOcbBo9y8gvy7+sXuGF5k4nHXNs46Ew1gThQPFtZjqgdiEi+A +5hYd5P2j0V9L9LprzM79 +-----END CERTIFICATE----- diff --git a/crypto/test/data/tls/x509-client-key-dsa.pem b/crypto/test/data/tls/x509-client-key-dsa.pem new file mode 100644 index 000000000..e4e9632c7 --- /dev/null +++ b/crypto/test/data/tls/x509-client-key-dsa.pem @@ -0,0 +1,15 @@ +-----BEGIN PRIVATE KEY----- +MIICZQIBADCCAjoGByqGSM44BAEwggItAoIBAQD72WVbGG6lMxeQKuSQlBibYPfh +4K2m/9hfL5xCrGClrShWOAQmpSG4W2f3uFTwBFdUpVfxoJrZD1azrrU4atN4/3qP +fLfNr4rJpLOkjLqTaMjoj6g2fh8jRGRSEFfVK/9Q/7TwUBqw+xW4eSTpikDwqKOO +rfV3JX5vvLvG1CIRUFeCyJLoOWAZtifMMuRXmkWJ6NfuB6eeN6A+kpDrRWiQqdOZ +34jUbWmcvy169tlJ0oIBvTP87oPrtwYtke9EyORSau08GB3wJW3rGywYx0B7xPeV +pRcStWKL5s4gS33sOUQpWd5II+390i/91nkctorbUGjm8Fdu2TY+Hp2AA6pJAiEA +7Df4zPZkuVA5jzUUelm8to7yUGx3ZusjKpRYiF1QBAkCggEBAM1a5w3TOpD01QC1 +iTWAtu/cSBDBE4piRj9/aN2FzCRZcqBMxWGpiT53mJWKWOIxn7nrQvoxZx6Lg4r7 +Y3X/7wHPqIOI2q6ODXGgwo8z2QU0Lr29HBYZUm1WbIrdSDL/7M7SVHT3HUCpxj/j +X4goQQ4fCy7JL7lXnxImtCMf8cHSu+uM1Z/aMYj+RNrCjDGJ5xaFcpGylFuN7Djj +Xvj9szhd1UyDlJ4LM3DQyibF6xSmfjLRPRbynbmlwZndMvT2re4xQqHa8tdu5gXi +GTim/Yd2DGQn+7UARaV+qPCV+C7cPYVUSLLKYGq5YtytfFpjkfuqbwMycSMcYmA2 +6NTxzAIEIgIgC6eNrpVR96umhuvIbLz6sy2YwlGFpkK+LLJOL2GmQ4g= +-----END PRIVATE KEY----- diff --git a/crypto/test/data/tls/x509-client-key-ecdsa.pem b/crypto/test/data/tls/x509-client-key-ecdsa.pem new file mode 100644 index 000000000..89232e303 --- /dev/null +++ b/crypto/test/data/tls/x509-client-key-ecdsa.pem @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGUAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHoweAIBAQQhANLHM3ugk0ZTEYNx +uKn3ytAv71M61ChZAjWdC9nW1U7zoAoGCCqGSM49AwEHoUQDQgAElnWoT+hfccJw ++ngAYNgMIn8gwwsOY8uYRnvi578o6JP83ZMNp/JVghXYSJxQu5kXBku2nbhe3cpL +/QvaFJmNew== +-----END PRIVATE KEY----- diff --git a/crypto/test/data/tls/x509-server-dsa.pem b/crypto/test/data/tls/x509-server-dsa.pem new file mode 100644 index 000000000..1078dbcbc --- /dev/null +++ b/crypto/test/data/tls/x509-server-dsa.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFmjCCBFKgAwIBAgIMVOBtTzLTG8B9QCZvMA0GCSqGSIb3DQEBCwUAMCMxITAf +BgNVBAMTGEJvdW5jeUNhc3RsZSBUTFMgVGVzdCBDQTAiGA8yMDE1MDIxNTA5NTYz +MVoYDzIwMzUwMjEwMDk1NjMxWjAjMSEwHwYDVQQDExhCb3VuY3lDYXN0bGUgVGVz +dCBTZXJ2ZXIwggNGMIICOQYHKoZIzjgEATCCAiwCggEBANblGd/puZYWDvmSMCx0 +AnQQcbmjUhB3MN68/fhkKFwBPU1QhJRiSEVDG1bnsUP55EQKDs1vpiSXgy89P3aT +cagq0M+urrN97MPeKoBF8sk4o6axruspxD41OyKhW68Nnk54E+3mEPABS4yYpsuE +hFfaZhOUXdA9aUFWnPN7oo7QlI+F7la8bluz8G8j81aMsEwjBdEKg+2Mp1+33NVa +IWEegnunVEkb0vJd/WwLZYj+OgmK4fn/qqIdRXIbjeNUvpAtklE5NrARswI0RXuX +yWxPfBrQSbWk3DQvbuWbEeSUrhYY67YbpPGA5Rng8awpxdXhvzsSmT9c6BlrLfF6 +IN0CIQDWtWHaMmlAVZW9p0Dmsj70sNHJxOYWlqjCEzF7axV3fwKCAQAgFZojuX/n +leri2E9C6b8cQTof46JZeAeG2Svk8I91cnIv0iXTHfyzWLWDAYnfeuMmt+nMA6/A +1K94YI1duc3iahLa5U3fOACWJdFtL/CAFVyNth7lDeHbWTFjM5HgA76pzmAfvFtZ +pcJp1AUZZB+3coKSr6ZrMagt1HhoefGyo7JkPpsxGiFEKB79rXkFi0AEsSnbduFE +czrg8DBdXm9//yUQnTw2pphcwLZt6t6Eq3Wrpu364Dn+hJegpLfA6uOhtRJw+7xv +5jkBbvIxp1PLZEn16qmPKMs3Im4QUa2u5F0nLYUGHi01i5OSn0UWnom8EcDis/0Q +CrkyBaiMaNkkA4IBBQACggEAQob2cpVeV4uwnX8XutQLro6BkEFMhpaQLUzbI97J +Nh1OUMnW3K2KCCdhygTYfH3j2S8ys4W30zutHyhiApUdYUZKxNXXu4+NPoLwCyAE +rrN5db5QgVx8aOG/Gfmp4POMpeGKioXgOsSWpUB0uyedgT4sszq/vuZc455HiS07 +LTlaJjeIQFtKdVYXGKNWqP/WLRnjSY9IXA5hxBXvlNAVGS/M4TvBWURUJF33THTq +ioS0DYJ9Ikyn2fsgLgSRRyNU7Y5945yUhY5p6E6Njk0ZBB+2YUtB6TQhPvEY/G48 +xwH4hTZppmmfu2UIE+YlsWv10buTOT+mxU/5LjDI6RQM2KN2MHQwDAYDVR0TAQH/ +BAIwADATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHQ8BAf8EBQMDB4AAMB0GA1Ud +DgQWBBS8bllTQWk2fm2R6XSZEIoRTd6/+zAfBgNVHSMEGDAWgBT2Y6+vo+Lv7g7l +srFGKGp4KTIe6TANBgkqhkiG9w0BAQsFAAOCATEAptRUkWUT+MdvD7v733B6Gad+ +wO0G9n7Au7ZsS6NVPxc4DrozFyyhPU1uOl1koUyYQP52V1lkm1+rS7tQXm4+32iz +bLwDCYn4LD1IZQ2hTNY/g/U0oA1dp3ZOJeydZDZ9Bm1NWYeWqfHk/ZiHMdrEdIUo +7Zkg1T0ZBvmBXTUJzeDqIV0fMotFOQBJg5avyCcX56jHXbu2AmGQsQf6NoniXG37 +wY/xiPSUUmOKjAU/B4tc24ADa5r37JzlHbpOGe1nTb8AYxjyPDdjO4Um2BugKE+K +rq+NJMg8Ej2sXLOnS2FweCoIR+RXGAUUBizlHMKJ2UGQ5sCX7U86qvniMcO8CsXR +7eSkBTYpxVLENxb2zf3g22972QWuL9eHyQfuO5dca2JnenZv1aIrhTH59fX8Sw== +-----END CERTIFICATE----- diff --git a/crypto/test/data/tls/x509-server-ecdsa.pem b/crypto/test/data/tls/x509-server-ecdsa.pem new file mode 100644 index 000000000..221fce99a --- /dev/null +++ b/crypto/test/data/tls/x509-server-ecdsa.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICqzCCAWOgAwIBAgIMVOBhgRR/e3iAhKcbMA0GCSqGSIb3DQEBCwUAMCMxITAf +BgNVBAMTGEJvdW5jeUNhc3RsZSBUTFMgVGVzdCBDQTAiGA8yMDE1MDIxNTA5MDYw +OVoYDzIwMzUwMjEwMDkwNjA5WjAjMSEwHwYDVQQDExhCb3VuY3lDYXN0bGUgVGVz +dCBTZXJ2ZXIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQzME1njDHqizStYiqf +xC45McfdqtcDFCsyik7g7JwwGBzDI3WTP5stb8gLHwGARqkaTIDr/wau+N12bIxp +Tj6Co3YwdDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1Ud +DwEB/wQFAwMHgAAwHQYDVR0OBBYEFOaifCD845nra+asxN59LzV1LlkxMB8GA1Ud +IwQYMBaAFPZjr6+j4u/uDuWysUYoangpMh7pMA0GCSqGSIb3DQEBCwUAA4IBMQCc +wMTPTd/82sDeJkN6B8M2AFfLf/0uw01/2I/UQp2rJCJu1Yps9S1foHz939o4qJA3 ++kieb3eVE8rcMQHMv42hagj09LmYY1Unzdu8xJDMq7gDIph72Fjy5YFqb9je79C4 +JPOadGsAsG9OY9DxTKsHyiX3Mqztx1hUQ0mNiAyaFEDGus+ZhSGMdHj0uR1LqZL9 +9OgszZY0UomZfhwnPg2sHumdh+13RZ38w33b43LpCcyu7v05szquqJ8lnol8j10r +6sH1xXZmb6OJIXZeHTnX5Dv1z0/R8qyG3gyVU7sP+8KVk529Q/YjIJ8YEV1LSERW +9cKbI+8DMxVE/z01gd0YLqpPcDSfzGUTww+lMWyGQ+KDUD2bC2O4LbZhzT+ZxCPN ++mw+T5KV78wcG02PThMf +-----END CERTIFICATE----- diff --git a/crypto/test/data/tls/x509-server-key-dsa.pem b/crypto/test/data/tls/x509-server-key-dsa.pem new file mode 100644 index 000000000..d6073b31f --- /dev/null +++ b/crypto/test/data/tls/x509-server-key-dsa.pem @@ -0,0 +1,15 @@ +-----BEGIN PRIVATE KEY----- +MIICZAIBADCCAjkGByqGSM44BAEwggIsAoIBAQDW5Rnf6bmWFg75kjAsdAJ0EHG5 +o1IQdzDevP34ZChcAT1NUISUYkhFQxtW57FD+eRECg7Nb6Ykl4MvPT92k3GoKtDP +rq6zfezD3iqARfLJOKOmsa7rKcQ+NTsioVuvDZ5OeBPt5hDwAUuMmKbLhIRX2mYT +lF3QPWlBVpzze6KO0JSPhe5WvG5bs/BvI/NWjLBMIwXRCoPtjKdft9zVWiFhHoJ7 +p1RJG9LyXf1sC2WI/joJiuH5/6qiHUVyG43jVL6QLZJROTawEbMCNEV7l8lsT3wa +0Em1pNw0L27lmxHklK4WGOu2G6TxgOUZ4PGsKcXV4b87Epk/XOgZay3xeiDdAiEA +1rVh2jJpQFWVvadA5rI+9LDRycTmFpaowhMxe2sVd38CggEAIBWaI7l/55Xq4thP +Qum/HEE6H+OiWXgHhtkr5PCPdXJyL9Il0x38s1i1gwGJ33rjJrfpzAOvwNSveGCN +XbnN4moS2uVN3zgAliXRbS/wgBVcjbYe5Q3h21kxYzOR4AO+qc5gH7xbWaXCadQF +GWQft3KCkq+mazGoLdR4aHnxsqOyZD6bMRohRCge/a15BYtABLEp23bhRHM64PAw +XV5vf/8lEJ08NqaYXMC2berehKt1q6bt+uA5/oSXoKS3wOrjobUScPu8b+Y5AW7y +MadTy2RJ9eqpjyjLNyJuEFGtruRdJy2FBh4tNYuTkp9FFp6JvBHA4rP9EAq5MgWo +jGjZJAQiAiBhYRIk49XUmvOqUx953A+n8/KWUfyZyTHPkcIXBvW+Ig== +-----END PRIVATE KEY----- diff --git a/crypto/test/data/tls/x509-server-key-ecdsa.pem b/crypto/test/data/tls/x509-server-key-ecdsa.pem new file mode 100644 index 000000000..01fe38567 --- /dev/null +++ b/crypto/test/data/tls/x509-server-key-ecdsa.pem @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGUAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHoweAIBAQQhALoiXMjOXuPkNVT6 +g/8PnBmXj8wEvWXCyrpO+fh9EMTdoAoGCCqGSM49AwEHoUQDQgAEMzBNZ4wx6os0 +rWIqn8QuOTHH3arXAxQrMopO4OycMBgcwyN1kz+bLW/ICx8BgEapGkyA6/8Grvjd +dmyMaU4+gg== +-----END PRIVATE KEY----- diff --git a/crypto/test/lib/nunit.core.dll b/crypto/test/lib/nunit.core.dll index f58c07d42..8d99c637d 100644 --- a/crypto/test/lib/nunit.core.dll +++ b/crypto/test/lib/nunit.core.dll Binary files differdiff --git a/crypto/test/lib/nunit.core.interfaces.dll b/crypto/test/lib/nunit.core.interfaces.dll index cdf50b687..70a76b21c 100644 --- a/crypto/test/lib/nunit.core.interfaces.dll +++ b/crypto/test/lib/nunit.core.interfaces.dll Binary files differdiff --git a/crypto/test/lib/nunit.framework.dll b/crypto/test/lib/nunit.framework.dll index c7b1c65d9..ba484ba8c 100644 --- a/crypto/test/lib/nunit.framework.dll +++ b/crypto/test/lib/nunit.framework.dll Binary files differdiff --git a/crypto/test/src/asn1/test/AllTests.cs b/crypto/test/src/asn1/test/AllTests.cs index a1ae8fd48..ad2f90362 100644 --- a/crypto/test/src/asn1/test/AllTests.cs +++ b/crypto/test/src/asn1/test/AllTests.cs @@ -9,24 +9,22 @@ namespace Org.BouncyCastle.Asn1.Tests { public static void Main(string[] args) { -// junit.textui.TestRunner.run(suite()); - EventListener el = new NullListener(); - suite().Run(el); + Suite.Run(new NullListener(), NUnit.Core.TestFilter.Empty); } - public static TestSuite suite() + [Suite] + public static TestSuite Suite { - TestSuite suite = new TestSuite("ASN.1 tests"); - - suite.Add(new AllTests()); - - // TODO Add these tests to RegressionTest list - suite.Add(new Asn1SequenceParserTest()); - suite.Add(new OctetStringTest()); - suite.Add(new ParseTest()); - suite.Add(new TimeTest()); - - return suite; + get + { + TestSuite suite = new TestSuite("ASN.1 tests"); + // TODO Add these tests to RegressionTest list + suite.Add(new Asn1SequenceParserTest()); + suite.Add(new OctetStringTest()); + suite.Add(new ParseTest()); + suite.Add(new TimeTest()); + return suite; + } } } } diff --git a/crypto/test/src/cms/test/AllTests.cs b/crypto/test/src/cms/test/AllTests.cs index 1ce3b7c8d..b7ac7644b 100644 --- a/crypto/test/src/cms/test/AllTests.cs +++ b/crypto/test/src/cms/test/AllTests.cs @@ -9,27 +9,26 @@ namespace Org.BouncyCastle.Cms.Tests { public class AllTests { - public static void Main( - string[] args) + public static void Main(string[] args) { - //junit.textui.TestRunner.run(suite()); - EventListener el = new NullListener(); - suite().Run(el); + Suite.Run(new NullListener(), NUnit.Core.TestFilter.Empty); } - public static TestSuite suite() + [Suite] + public static TestSuite Suite { - TestSuite suite = new TestSuite("CMS Tests"); - - suite.Add(new CompressedDataTest()); - suite.Add(new CompressedDataStreamTest()); - suite.Add(new EnvelopedDataTest()); - suite.Add(new EnvelopedDataStreamTest()); - suite.Add(new Rfc4134Test()); - suite.Add(new SignedDataTest()); - suite.Add(new SignedDataStreamTest()); - - return suite; + get + { + TestSuite suite = new TestSuite("CMS Tests"); + suite.Add(new CompressedDataTest()); + suite.Add(new CompressedDataStreamTest()); + suite.Add(new EnvelopedDataTest()); + suite.Add(new EnvelopedDataStreamTest()); + suite.Add(new Rfc4134Test()); + suite.Add(new SignedDataTest()); + suite.Add(new SignedDataStreamTest()); + return suite; + } } } } diff --git a/crypto/test/src/crypto/io/test/AllTests.cs b/crypto/test/src/crypto/io/test/AllTests.cs index 0296a2dc0..5c8c759f9 100644 --- a/crypto/test/src/crypto/io/test/AllTests.cs +++ b/crypto/test/src/crypto/io/test/AllTests.cs @@ -7,21 +7,20 @@ namespace Org.BouncyCastle.Crypto.IO.Tests { public class AllTests { - public static void Main( - string[] args) - { -// junit.textui.TestRunner.run(suite()); - EventListener el = new NullListener(); - suite().Run(el); - } + public static void Main(string[] args) + { + Suite.Run(new NullListener(), NUnit.Core.TestFilter.Empty); + } - public static TestSuite suite() - { - TestSuite suite = new TestSuite("IO tests"); - - suite.Add(new CipherStreamTest()); - - return suite; - } + [Suite] + public static TestSuite Suite + { + get + { + TestSuite suite = new TestSuite("IO tests"); + suite.Add(new CipherStreamTest()); + return suite; + } + } } } diff --git a/crypto/test/src/crypto/test/AllTests.cs b/crypto/test/src/crypto/test/AllTests.cs index 1cb1b965d..3d8ef5602 100644 --- a/crypto/test/src/crypto/test/AllTests.cs +++ b/crypto/test/src/crypto/test/AllTests.cs @@ -10,19 +10,24 @@ namespace Org.BouncyCastle.Crypto.Tests [TestFixture] public class AllTests { - [Suite] - public static TestSuite Suite - { - get - { - TestSuite suite = new TestSuite("Lightweight Crypto Tests"); - suite.Add(new AllTests()); - suite.Add(new GcmReorderTest()); - return suite; - } - } + public static void Main(string[] args) + { + Suite.Run(new NullListener(), NUnit.Core.TestFilter.Empty); + } - [Test] + [Suite] + public static TestSuite Suite + { + get + { + TestSuite suite = new TestSuite("Lightweight Crypto Tests"); + suite.Add(new AllTests()); + suite.Add(new GcmReorderTest()); + return suite; + } + } + + [Test] public void TestCrypto() { foreach (Org.BouncyCastle.Utilities.Test.ITest test in RegressionTest.tests) @@ -35,13 +40,5 @@ namespace Org.BouncyCastle.Crypto.Tests } } } - - public static void Main( - string[] args) - { - //junit.textui.TestRunner.run(suite()); - EventListener el = new NullListener(); - Suite.Run(el); - } } } diff --git a/crypto/test/src/crypto/test/CCMTest.cs b/crypto/test/src/crypto/test/CCMTest.cs index 4a54fb4f9..8c46e11e7 100644 --- a/crypto/test/src/crypto/test/CCMTest.cs +++ b/crypto/test/src/crypto/test/CCMTest.cs @@ -81,7 +81,38 @@ namespace Org.BouncyCastle.Crypto.Tests // checkVectors(4, ccm, K4, 112, N4, A4, A4, T5, C5); - // + // decryption with output specified, non-zero offset. + ccm.Init(false, new AeadParameters(new KeyParameter(K2), 48, N2, A2)); + + byte[] inBuf = new byte[C2.Length + 10]; + byte[] outBuf = new byte[ccm.GetOutputSize(C2.Length) + 10]; + + Array.Copy(C2, 0, inBuf, 10, C2.Length); + + int len = ccm.ProcessPacket(inBuf, 10, C2.Length, outBuf, 10); + byte[] output = ccm.ProcessPacket(C2, 0, C2.Length); + + if (len != output.Length || !isEqual(output, outBuf, 10)) + { + Fail("decryption output incorrect"); + } + + // encryption with output specified, non-zero offset. + ccm.Init(true, new AeadParameters(new KeyParameter(K2), 48, N2, A2)); + + int inLen = len; + inBuf = outBuf; + outBuf = new byte[ccm.GetOutputSize(inLen) + 10]; + + len = ccm.ProcessPacket(inBuf, 10, inLen, outBuf, 10); + output = ccm.ProcessPacket(inBuf, 10, inLen); + + if (len != output.Length || !isEqual(output, outBuf, 10)) + { + Fail("encryption output incorrect"); + } + + // // exception tests // @@ -121,6 +152,17 @@ namespace Org.BouncyCastle.Crypto.Tests } } + private bool isEqual(byte[] exp, byte[] other, int off) + { + for (int i = 0; i != exp.Length; i++) + { + if (exp[i] != other[off + i]) + return false; + } + + return true; + } + private void checkVectors( int count, CcmBlockCipher ccm, @@ -203,7 +245,8 @@ namespace Org.BouncyCastle.Crypto.Tests if (!AreEqual(p, dec)) { - Fail("decrypted stream fails to match in test " + count + " with " + additionalDataType); + Fail("decrypted stream fails to match in test " + count + " with " + additionalDataType, + Hex.ToHexString(p), Hex.ToHexString(dec)); } if (!AreEqual(t, ccm.GetMac())) diff --git a/crypto/test/src/crypto/test/RegressionTest.cs b/crypto/test/src/crypto/test/RegressionTest.cs index 27d6bb0e9..0b7a0f72d 100644 --- a/crypto/test/src/crypto/test/RegressionTest.cs +++ b/crypto/test/src/crypto/test/RegressionTest.cs @@ -118,7 +118,8 @@ namespace Org.BouncyCastle.Crypto.Tests new SipHashTest(), new Poly1305Test(), new OcbTest(), - new SM3DigestTest() + new SM3DigestTest(), + new X931SignerTest() }; public static void Main( diff --git a/crypto/test/src/crypto/test/SRP6Test.cs b/crypto/test/src/crypto/test/SRP6Test.cs index 3b80e2c16..6b64df924 100644 --- a/crypto/test/src/crypto/test/SRP6Test.cs +++ b/crypto/test/src/crypto/test/SRP6Test.cs @@ -23,15 +23,7 @@ namespace Org.BouncyCastle.Crypto.Tests return new BigInteger(1, Hex.Decode(hex)); } - // 1024 bit example prime from RFC5054 and corresponding generator - private static readonly BigInteger N_1024 = FromHex("EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C" - + "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4" - + "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29" - + "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A" - + "FD5138FE8376435B9FC61D2FC0EB06E3"); - private static readonly BigInteger g_1024 = BigInteger.Two; - - private readonly SecureRandom random = new SecureRandom(); + private readonly SecureRandom random = new SecureRandom(); public override string Name { @@ -42,9 +34,9 @@ namespace Org.BouncyCastle.Crypto.Tests { rfc5054AppendixBTestVectors(); - testMutualVerification(N_1024, g_1024); - testClientCatchesBadB(N_1024, g_1024); - testServerCatchesBadA(N_1024, g_1024); + testMutualVerification(Srp6StandardGroups.rfc5054_1024); + testClientCatchesBadB(Srp6StandardGroups.rfc5054_1024); + testServerCatchesBadA(Srp6StandardGroups.rfc5054_1024); testWithRandomParams(256); testWithRandomParams(384); @@ -56,8 +48,8 @@ namespace Org.BouncyCastle.Crypto.Tests byte[] I = Encoding.UTF8.GetBytes("alice"); byte[] P = Encoding.UTF8.GetBytes("password123"); byte[] s = Hex.Decode("BEB25379D1A8581EB5A727673A2441EE"); - BigInteger N = N_1024; - BigInteger g = g_1024; + BigInteger N = Srp6StandardGroups.rfc5054_1024.N; + BigInteger g = Srp6StandardGroups.rfc5054_1024.G; BigInteger a = FromHex("60975527035CF2AD1989806F0407210BC81EDC04E2762A56AFD529DDDA2D4393"); BigInteger b = FromHex("E487CB59D31AC550471E81F00F6928E01DDA08E974A004F49E61F5D105284D20"); @@ -148,13 +140,10 @@ namespace Org.BouncyCastle.Crypto.Tests paramGen.Init(bits, 25, random); DHParameters parameters = paramGen.GenerateParameters(); - BigInteger g = parameters.G; - BigInteger p = parameters.P; - - testMutualVerification(p, g); + testMutualVerification(new Srp6GroupParameters(parameters.P, parameters.G)); } - private void testMutualVerification(BigInteger N, BigInteger g) + private void testMutualVerification(Srp6GroupParameters group) { byte[] I = Encoding.UTF8.GetBytes("username"); byte[] P = Encoding.UTF8.GetBytes("password"); @@ -162,16 +151,16 @@ namespace Org.BouncyCastle.Crypto.Tests random.NextBytes(s); Srp6VerifierGenerator gen = new Srp6VerifierGenerator(); - gen.Init(N, g, new Sha256Digest()); + gen.Init(group, new Sha256Digest()); BigInteger v = gen.GenerateVerifier(s, I, P); Srp6Client client = new Srp6Client(); - client.Init(N, g, new Sha256Digest(), random); + client.Init(group, new Sha256Digest(), random); Srp6Server server = new Srp6Server(); - server.Init(N, g, v, new Sha256Digest(), random); + server.Init(group, v, new Sha256Digest(), random); - BigInteger A = client.GenerateClientCredentials(s, I, P); + BigInteger A = client.GenerateClientCredentials(s, I, P); BigInteger B = server.GenerateServerCredentials(); BigInteger clientS = client.CalculateSecret(B); @@ -183,7 +172,7 @@ namespace Org.BouncyCastle.Crypto.Tests } } - private void testClientCatchesBadB(BigInteger N, BigInteger g) + private void testClientCatchesBadB(Srp6GroupParameters group) { byte[] I = Encoding.UTF8.GetBytes("username"); byte[] P = Encoding.UTF8.GetBytes("password"); @@ -191,7 +180,7 @@ namespace Org.BouncyCastle.Crypto.Tests random.NextBytes(s); Srp6Client client = new Srp6Client(); - client.Init(N, g, new Sha256Digest(), random); + client.Init(group, new Sha256Digest(), random); client.GenerateClientCredentials(s, I, P); @@ -207,7 +196,7 @@ namespace Org.BouncyCastle.Crypto.Tests try { - client.CalculateSecret(N); + client.CalculateSecret(group.N); Fail("Client failed to detect invalid value for 'B'"); } catch (CryptoException) @@ -216,7 +205,7 @@ namespace Org.BouncyCastle.Crypto.Tests } } - private void testServerCatchesBadA(BigInteger N, BigInteger g) + private void testServerCatchesBadA(Srp6GroupParameters group) { byte[] I = Encoding.UTF8.GetBytes("username"); byte[] P = Encoding.UTF8.GetBytes("password"); @@ -224,11 +213,11 @@ namespace Org.BouncyCastle.Crypto.Tests random.NextBytes(s); Srp6VerifierGenerator gen = new Srp6VerifierGenerator(); - gen.Init(N, g, new Sha256Digest()); + gen.Init(group, new Sha256Digest()); BigInteger v = gen.GenerateVerifier(s, I, P); Srp6Server server = new Srp6Server(); - server.Init(N, g, v, new Sha256Digest(), random); + server.Init(group, v, new Sha256Digest(), random); server.GenerateServerCredentials(); @@ -244,7 +233,7 @@ namespace Org.BouncyCastle.Crypto.Tests try { - server.CalculateSecret(N); + server.CalculateSecret(group.N); Fail("Client failed to detect invalid value for 'A'"); } catch (CryptoException) diff --git a/crypto/test/src/crypto/test/X931SignerTest.cs b/crypto/test/src/crypto/test/X931SignerTest.cs new file mode 100644 index 000000000..d03cbc8e4 --- /dev/null +++ b/crypto/test/src/crypto/test/X931SignerTest.cs @@ -0,0 +1,145 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; + +using NUnit.Framework; + +namespace Org.BouncyCastle.Crypto.Tests +{ + [TestFixture] + public class X931SignerTest + : SimpleTest + { + public override string Name + { + get { return "X931Signer"; } + } + + public override void PerformTest() + { + BigInteger rsaPubMod = new BigInteger(Base64.Decode("AIASoe2PQb1IP7bTyC9usjHP7FvnUMVpKW49iuFtrw/dMpYlsMMoIU2jupfifDpdFxIktSB4P+6Ymg5WjvHKTIrvQ7SR4zV4jaPTu56Ys0pZ9EDA6gb3HLjtU+8Bb1mfWM+yjKxcPDuFjwEtjGlPHg1Vq+CA9HNcMSKNn2+tW6qt")); + BigInteger rsaPubExp = new BigInteger(Base64.Decode("EQ==")); + BigInteger rsaPrivMod = new BigInteger(Base64.Decode("AIASoe2PQb1IP7bTyC9usjHP7FvnUMVpKW49iuFtrw/dMpYlsMMoIU2jupfifDpdFxIktSB4P+6Ymg5WjvHKTIrvQ7SR4zV4jaPTu56Ys0pZ9EDA6gb3HLjtU+8Bb1mfWM+yjKxcPDuFjwEtjGlPHg1Vq+CA9HNcMSKNn2+tW6qt")); + BigInteger rsaPrivDP = new BigInteger(Base64.Decode("JXzfzG5v+HtLJIZqYMUefJfFLu8DPuJGaLD6lI3cZ0babWZ/oPGoJa5iHpX4Ul/7l3s1PFsuy1GhzCdOdlfRcQ==")); + BigInteger rsaPrivDQ = new BigInteger(Base64.Decode("YNdJhw3cn0gBoVmMIFRZzflPDNthBiWy/dUMSRfJCxoZjSnr1gysZHK01HteV1YYNGcwPdr3j4FbOfri5c6DUQ==")); + BigInteger rsaPrivExp = new BigInteger(Base64.Decode("DxFAOhDajr00rBjqX+7nyZ/9sHWRCCp9WEN5wCsFiWVRPtdB+NeLcou7mWXwf1Y+8xNgmmh//fPV45G2dsyBeZbXeJwB7bzx9NMEAfedchyOwjR8PYdjK3NpTLKtZlEJ6Jkh4QihrXpZMO4fKZWUm9bid3+lmiq43FwW+Hof8/E=")); + BigInteger rsaPrivP = new BigInteger(Base64.Decode("AJ9StyTVW+AL/1s7RBtFwZGFBgd3zctBqzzwKPda6LbtIFDznmwDCqAlIQH9X14X7UPLokCDhuAa76OnDXb1OiE=")); + BigInteger rsaPrivQ = new BigInteger(Base64.Decode("AM3JfD79dNJ5A3beScSzPtWxx/tSLi0QHFtkuhtSizeXdkv5FSba7lVzwEOGKHmW829bRoNxThDy4ds1IihW1w0=")); + BigInteger rsaPrivQinv = new BigInteger(Base64.Decode("Lt0g7wrsNsQxuDdB8q/rH8fSFeBXMGLtCIqfOec1j7FEIuYA/ACiRDgXkHa0WgN7nLXSjHoy630wC5Toq8vvUg==")); + RsaKeyParameters rsaPublic = new RsaKeyParameters(false, rsaPubMod, rsaPubExp); + RsaPrivateCrtKeyParameters rsaPrivate = new RsaPrivateCrtKeyParameters(rsaPrivMod, rsaPubExp, rsaPrivExp, rsaPrivP, rsaPrivQ, rsaPrivDP, rsaPrivDQ, rsaPrivQinv); + + byte[] msg = new byte[] { 1, 6, 3, 32, 7, 43, 2, 5, 7, 78, 4, 23 }; + + X931Signer signer = new X931Signer(new RsaEngine(), new Sha1Digest()); + signer.Init(true, rsaPrivate); + signer.BlockUpdate(msg, 0, msg.Length); + byte[] sig = signer.GenerateSignature(); + + signer = new X931Signer(new RsaEngine(), new Sha1Digest()); + signer.Init(false, rsaPublic); + signer.BlockUpdate(msg, 0, msg.Length); + if (!signer.VerifySignature(sig)) + { + Fail("X9.31 Signer failed."); + } + + ShouldPassSignatureTest1(); + ShouldPassSignatureTest2(); + ShouldPassSignatureTest3(); + } + + private void ShouldPassSignatureTest1() + { + BigInteger n = new BigInteger("c9be1b28f8caccca65d86cc3c9bbcc13eccc059df3b80bd2292b811eff3aa0dd75e1e85c333b8e3fa9bed53bb20f5359ff4e6900c5e9a388e3a4772a583a79e2299c76582c2b27694b65e9ba22e66bfb817f8b70b22206d7d8ae488c86dbb7137c26d5eff9b33c90e6cee640630313b7a715802e15142fef498c404a8de19674974785f0f852e2d470fe85a2e54ffca9f5851f672b71df691785a5cdabe8f14aa628942147de7593b2cf962414a5b59c632c4e14f1768c0ab2e9250824beea60a3529f11bf5e070ce90a47686eb0be1086fb21f0827f55295b4a48307db0b048c05a4aec3f488c576ca6f1879d354224c7e84cbcd8e76dd217a3de54dba73c35", 16); + BigInteger e = new BigInteger("e75b1b", 16); + byte[] msg = Hex.Decode("5bb0d1c0ef9b5c7af2477fe08d45523d3842a4b2db943f7033126c2a7829bacb3d2cfc6497ec91688189e81b7f8742488224ba320ce983ce9480722f2cc5bc42611f00bb6311884f660ccc244788378673532edb05284fd92e83f6f6dab406209032e6af9a33c998677933e32d6fb95fd27408940d7728f9c9c40267ca1d20ce"); + byte[] sig = Hex.Decode("0fe8bb8e3109a1eb7489ef35bf4c1a0780071da789c8bd226a4170538eafefdd30b732d628f0e87a0b9450051feae9754d4fb61f57862d10f0bacc4f660d13281d0cd1141c006ade5186ff7d961a4c6cd0a4b352fc1295c5afd088f80ac1f8e192ef116a010a442655fe8ff5eeacea15807906fb0f0dfa86e680d4c005872357f7ece9aa4e20b15d5f709b30f08648ecaa34f2fbf54eb6b414fa2ff6f87561f70163235e69ccb4ac82a2e46d3be214cc2ef5263b569b2d8fd839b21a9e102665105ea762bda25bb446cfd831487a6b846100dee113ae95ae64f4af22c428c87bab809541c962bb3a56d4c86588e0af4ebc7fcc66dadced311051356d3ea745f7"); + + RsaKeyParameters rsaPublic = new RsaKeyParameters(false, n, e); + X931Signer signer = new X931Signer(new RsaEngine(), new Sha1Digest()); + + signer.Init(false, rsaPublic); + + signer.BlockUpdate(msg, 0, msg.Length); + + if (!signer.VerifySignature(sig)) + { + Fail("RSA X931 verify test 1 failed."); + } + } + + private void ShouldPassSignatureTest2() + { + BigInteger n = new BigInteger("b746ba6c3c0be64bbe33aa55b2929b0af4e86d773d44bfe5914db9287788c4663984b61a418d2eecca30d752ff6b620a07ec72eeb2b422d2429da352407b99982800b9dd7697be6a7b1baa98ca5f4fc2fe33400f20b9dba337ac25c987804165d4a6e0ee4d18eabd6de5abdfe578cae6713ff91d16c80a5bb20217fe614d9509e75a43e1825327b9da8f0a9f6eeaa1c04b69fb4bacc073569fff4ab491becbe6d0441d437fc3fa823239c4a0f75321666b68dd3f66e2dd394089a15bcc288a68a4eb0a48e17d639743b9dea0a91cc35820544732aff253f8ca9967c609dc01c2f8cd0313a7a91cfa94ff74289a1d2b6f19d1811f4b9a65f4cce9e5759b4cc64f", 16); + BigInteger e = new BigInteger("dcbbdb", 16); + byte[] msg = Hex.Decode("a5d3c8a060f897bbbc20ae0955052f37fbc70986b6e11c65075c9f457142bfa93856897c69020aa81a91b5e4f39e05cdeecc63395ab849c8262ca8bc5c96870aecb8edb0aba0024a9bdb71e06de6100344e5c318bc979ef32b8a49a8278ba99d4861bce42ebbc5c8c666aaa6cac39aff8779f2cae367620f9edd4cb1d80b6c8c"); + byte[] sig = Hex.Decode("39fbbd1804c689a533b0043f84da0f06081038c0fbf31e443e46a05e58f50de5198bbca40522afefaba3aed7082a6cb93b1da39f1f5a42246bf64930781948d300549bef0f8d554ecfca60a1b1ecba95a7014ee4545ad4f0c4e3a31942c6738b4ccd6244b6a21267dadf0826a5f713f13b1f5a9ab8501d957a26d4948278ac67851071a315674bdab173bfef2c2690c8373da6bf3d69f30c0e5da8883de872f59521b40793854085641adf98d13db991c5d0a8aaa0222934fa33332e90ef0b954e195cb267d6ffb36c96e14d1ec7b915a87598b4461a3146566354dc2ae748c84ee0cd46543b53ebff8cdf47725b280a1f799fb6ebb4a31ad2bdd5178250f83a"); + + RsaKeyParameters rsaPublic = new RsaKeyParameters(false, n, e); + X931Signer signer = new X931Signer(new RsaEngine(), new Sha224Digest()); + + signer.Init(false, rsaPublic); + + signer.BlockUpdate(msg, 0, msg.Length); + + if (!signer.VerifySignature(sig)) + { + Fail("RSA X931 verify test 2 failed."); + } + } + + private void ShouldPassSignatureTest3() + { + BigInteger n = new BigInteger("dcb5686a3d2063a3f9cf7b9b32d2d3765b4c449b09b4960245a9111cd3b0cbd3260496885b8e1fa5db33b03efcc759d9c1afe29d93c6faebc7e0efada334b5b9a29655e2da2c8f11103d8203be311feab7ae88e9f1b2ec7d8fc655d77202b1681dd9717ec0f525b35584987e19539635a1ed23ca482a00149c609a23dc1645fd", 16); + BigInteger e = new BigInteger("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dc9f7", 16); + BigInteger d = new BigInteger("189d6345099098992e0c9ca5f281e1338092342fa0acc85cc2a111f30f9bd2fb4753cd1a48ef0ddca9bf1af33ec76fb2e23a9fb4896c26f2235b516f7c05ef7ae81e70f4b491a5fedba9b935e9c76d761a813ce7776ff8a1e5efe1166ff2eca26aa900da88c908d51af9de26977fe39719cc781df32216fa41b838f0c63803c3", 16); + + byte[] msg = Hex.Decode("911475c6e210ef4ac65b6fe8d2bfe5e01b959771b137c4ef69b88716e0d2ff9ebc1fad0f358c1dd7d50cc99a7b893ac9a6207076f08d8467d9e48c69c683bfe64a44dabaa3f7c243880f6ab7229bf7bb587822314fc5de5131983bfb2eef8b4bc1eac36f353724b567cd1ae8cddd64ddb7057549d5c81ad5fa3b5e751f00abf5"); + byte[] sig = Hex.Decode("02c50ec0ac8a7f38ef5630c396964d6a6daaa7e3083ab5b57fa2a2632f3b70e2e85c8456cd774d45d7e44fcb063f0f04fff9f1e3adfda11272535a92cb59320b190b5ee4261f23d6ceaa925df3a7bfa42e26bf61ea9645d9d64b3c90a820802768a6e209c9f83705375a3867afccc037e8242a98fa4c3db6b2d9877754d47289"); + + RsaKeyParameters rsaPublic = new RsaKeyParameters(false, n, e); + X931Signer signer = new X931Signer(new RsaEngine(), new Sha1Digest()); + + signer.Init(true, new RsaKeyParameters(true, n, d)); + + signer.BlockUpdate(msg, 0, msg.Length); + + byte[] s = signer.GenerateSignature(); + + if (!Arrays.AreEqual(sig, s)) + { + Fail("RSA X931 sig test 3 failed."); + } + + signer.Init(false, rsaPublic); + + signer.BlockUpdate(msg, 0, msg.Length); + + if (!signer.VerifySignature(sig)) + { + Fail("RSA X931 verify test 3 failed."); + } + } + + public static void Main(string[] args) + { + RunTest(new X931SignerTest()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } +} diff --git a/crypto/test/src/crypto/tls/test/DtlsProtocolTest.cs b/crypto/test/src/crypto/tls/test/DtlsProtocolTest.cs new file mode 100644 index 000000000..bc99ccc63 --- /dev/null +++ b/crypto/test/src/crypto/tls/test/DtlsProtocolTest.cs @@ -0,0 +1,102 @@ +using System; +using System.IO; +using System.Threading; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +using NUnit.Framework; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + [TestFixture] + public class DtlsProtocolTest + { + [Test] + public void TestClientServer() + { + SecureRandom secureRandom = new SecureRandom(); + + DtlsClientProtocol clientProtocol = new DtlsClientProtocol(secureRandom); + DtlsServerProtocol serverProtocol = new DtlsServerProtocol(secureRandom); + + MockDatagramAssociation network = new MockDatagramAssociation(1500); + + Server server = new Server(serverProtocol, network.Server); + + Thread serverThread = new Thread(new ThreadStart(server.Run)); + serverThread.Start(); + + DatagramTransport clientTransport = network.Client; + + clientTransport = new UnreliableDatagramTransport(clientTransport, secureRandom, 0, 0); + + clientTransport = new LoggingDatagramTransport(clientTransport, Console.Out); + + MockDtlsClient client = new MockDtlsClient(null); + + DtlsTransport dtlsClient = clientProtocol.Connect(client, clientTransport); + + for (int i = 1; i <= 10; ++i) + { + byte[] data = new byte[i]; + Arrays.Fill(data, (byte)i); + dtlsClient.Send(data, 0, data.Length); + } + + byte[] buf = new byte[dtlsClient.GetReceiveLimit()]; + while (dtlsClient.Receive(buf, 0, buf.Length, 100) >= 0) + { + } + + dtlsClient.Close(); + + server.Shutdown(serverThread); + } + + internal class Server + { + private readonly DtlsServerProtocol mServerProtocol; + private readonly DatagramTransport mServerTransport; + private volatile bool isShutdown = false; + + internal Server(DtlsServerProtocol serverProtocol, DatagramTransport serverTransport) + { + this.mServerProtocol = serverProtocol; + this.mServerTransport = serverTransport; + } + + public void Run() + { + try + { + MockDtlsServer server = new MockDtlsServer(); + DtlsTransport dtlsServer = mServerProtocol.Accept(server, mServerTransport); + byte[] buf = new byte[dtlsServer.GetReceiveLimit()]; + while (!isShutdown) + { + int length = dtlsServer.Receive(buf, 0, buf.Length, 1000); + if (length >= 0) + { + dtlsServer.Send(buf, 0, length); + } + } + dtlsServer.Close(); + } + catch (Exception e) + { + Console.Error.WriteLine(e.StackTrace); + } + } + + internal void Shutdown(Thread serverThread) + { + if (!isShutdown) + { + isShutdown = true; + serverThread.Join(); + } + } + } + } +} diff --git a/crypto/test/src/crypto/tls/test/DtlsTestCase.cs b/crypto/test/src/crypto/tls/test/DtlsTestCase.cs new file mode 100644 index 000000000..d4af04fac --- /dev/null +++ b/crypto/test/src/crypto/tls/test/DtlsTestCase.cs @@ -0,0 +1,153 @@ +using System; +using System.IO; +using System.Threading; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +using NUnit.Framework; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + [TestFixture] + public class DtlsTestCase + { + private static void CheckDtlsVersion(ProtocolVersion version) + { + if (version != null && !version.IsDtls) + throw new InvalidOperationException("Non-DTLS version"); + } + + [Test, TestCaseSource(typeof(DtlsTestSuite), "Suite")] + public void RunTest(TlsTestConfig config) + { + CheckDtlsVersion(config.clientMinimumVersion); + CheckDtlsVersion(config.clientOfferVersion); + CheckDtlsVersion(config.serverMaximumVersion); + CheckDtlsVersion(config.serverMinimumVersion); + + SecureRandom secureRandom = new SecureRandom(); + + DtlsClientProtocol clientProtocol = new DtlsClientProtocol(secureRandom); + DtlsServerProtocol serverProtocol = new DtlsServerProtocol(secureRandom); + + MockDatagramAssociation network = new MockDatagramAssociation(1500); + + TlsTestClientImpl clientImpl = new TlsTestClientImpl(config); + TlsTestServerImpl serverImpl = new TlsTestServerImpl(config); + + Server server = new Server(this, serverProtocol, network.Server, serverImpl); + + Thread serverThread = new Thread(new ThreadStart(server.Run)); + serverThread.Start(); + + Exception caught = null; + try + { + DatagramTransport clientTransport = network.Client; + + if (TlsTestConfig.DEBUG) + { + clientTransport = new LoggingDatagramTransport(clientTransport, Console.Out); + } + + DtlsTransport dtlsClient = clientProtocol.Connect(clientImpl, clientTransport); + + for (int i = 1; i <= 10; ++i) + { + byte[] data = new byte[i]; + Arrays.Fill(data, (byte)i); + dtlsClient.Send(data, 0, data.Length); + } + + byte[] buf = new byte[dtlsClient.GetReceiveLimit()]; + while (dtlsClient.Receive(buf, 0, buf.Length, 100) >= 0) + { + } + + dtlsClient.Close(); + } + catch (Exception e) + { + caught = e; + LogException(caught); + } + + server.Shutdown(serverThread); + + // TODO Add checks that the various streams were closed + + Assert.AreEqual(config.expectFatalAlertConnectionEnd, clientImpl.FirstFatalAlertConnectionEnd, "Client fatal alert connection end"); + Assert.AreEqual(config.expectFatalAlertConnectionEnd, serverImpl.FirstFatalAlertConnectionEnd, "Server fatal alert connection end"); + + Assert.AreEqual(config.expectFatalAlertDescription, clientImpl.FirstFatalAlertDescription, "Client fatal alert description"); + Assert.AreEqual(config.expectFatalAlertDescription, serverImpl.FirstFatalAlertDescription, "Server fatal alert description"); + + if (config.expectFatalAlertConnectionEnd == -1) + { + Assert.IsNull(caught, "Unexpected client exception"); + Assert.IsNull(server.mCaught, "Unexpected server exception"); + } + } + + protected void LogException(Exception e) + { + if (TlsTestConfig.DEBUG) + { + Console.Error.WriteLine(e.StackTrace); + } + } + + internal class Server + { + private readonly DtlsTestCase mOuter; + private readonly DtlsServerProtocol mServerProtocol; + private readonly DatagramTransport mServerTransport; + private readonly TlsTestServerImpl mServerImpl; + + private volatile bool isShutdown = false; + internal Exception mCaught = null; + + internal Server(DtlsTestCase outer, DtlsServerProtocol serverProtocol, DatagramTransport serverTransport, TlsTestServerImpl serverImpl) + { + this.mOuter = outer; + this.mServerProtocol = serverProtocol; + this.mServerTransport = serverTransport; + this.mServerImpl = serverImpl; + } + + public void Run() + { + try + { + DtlsTransport dtlsServer = mServerProtocol.Accept(mServerImpl, mServerTransport); + byte[] buf = new byte[dtlsServer.GetReceiveLimit()]; + while (!isShutdown) + { + int length = dtlsServer.Receive(buf, 0, buf.Length, 100); + if (length >= 0) + { + dtlsServer.Send(buf, 0, length); + } + } + dtlsServer.Close(); + } + catch (Exception e) + { + mCaught = e; + mOuter.LogException(mCaught); + } + } + + internal void Shutdown(Thread serverThread) + { + if (!isShutdown) + { + isShutdown = true; + serverThread.Interrupt(); + serverThread.Join(); + } + } + } + } +} diff --git a/crypto/test/src/crypto/tls/test/DtlsTestSuite.cs b/crypto/test/src/crypto/tls/test/DtlsTestSuite.cs new file mode 100644 index 000000000..eb9d42e5f --- /dev/null +++ b/crypto/test/src/crypto/tls/test/DtlsTestSuite.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections; + +using NUnit.Framework; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + public class DtlsTestSuite + { + // Make the access to constants less verbose + internal class C : TlsTestConfig {} + + public DtlsTestSuite() + { + } + + public static IEnumerable Suite() + { + IList testSuite = new ArrayList(); + + AddFallbackTests(testSuite); + AddVersionTests(testSuite, ProtocolVersion.DTLSv10); + AddVersionTests(testSuite, ProtocolVersion.DTLSv12); + + return testSuite; + } + + private static void AddFallbackTests(IList testSuite) + { + { + TlsTestConfig c = CreateDtlsTestConfig(ProtocolVersion.DTLSv12); + c.clientFallback = true; + + testSuite.Add(new TestCaseData(c).SetName("FallbackGood")); + } + + /* + * NOTE: Temporarily disabled automatic test runs because of problems getting a clean exit + * of the DTLS server after a fatal alert. As of writing, manual runs show the correct + * alerts being raised + */ + + //{ + // TlsTestConfig c = CreateDtlsTestConfig(ProtocolVersion.DTLSv12); + // c.clientOfferVersion = ProtocolVersion.DTLSv10; + // c.clientFallback = true; + // c.ExpectServerFatalAlert(AlertDescription.inappropriate_fallback); + + // testSuite.Add(new TestCaseData(c).SetName("FallbackBad")); + //} + + { + TlsTestConfig c = CreateDtlsTestConfig(ProtocolVersion.DTLSv12); + c.clientOfferVersion = ProtocolVersion.DTLSv10; + + testSuite.Add(new TestCaseData(c).SetName("FallbackNone")); + } + } + + private static void AddVersionTests(IList testSuite, ProtocolVersion version) + { + string prefix = version.ToString() + .Replace(" ", "") + .Replace("\\", "") + .Replace(".", "") + + "_"; + + /* + * NOTE: Temporarily disabled automatic test runs because of problems getting a clean exit + * of the DTLS server after a fatal alert. As of writing, manual runs show the correct + * alerts being raised + */ + + //{ + // TlsTestConfig c = CreateDtlsTestConfig(version); + // c.clientAuth = C.CLIENT_AUTH_INVALID_VERIFY; + // c.ExpectServerFatalAlert(AlertDescription.decrypt_error); + + // testSuite.Add(new TestCaseData(c).SetName(prefix + "BadCertificateVerify")); + //} + + //{ + // TlsTestConfig c = CreateDtlsTestConfig(version); + // c.clientAuth = C.CLIENT_AUTH_INVALID_CERT; + // c.ExpectServerFatalAlert(AlertDescription.bad_certificate); + + // testSuite.Add(new TestCaseData(c).SetName(prefix + "BadClientCertificate")); + //} + + //{ + // TlsTestConfig c = CreateDtlsTestConfig(version); + // c.clientAuth = C.CLIENT_AUTH_NONE; + // c.serverCertReq = C.SERVER_CERT_REQ_MANDATORY; + // c.ExpectServerFatalAlert(AlertDescription.handshake_failure); + + // testSuite.Add(new TestCaseData(c).SetName(prefix + "BadMandatoryCertReqDeclined")); + //} + + { + TlsTestConfig c = CreateDtlsTestConfig(version); + + testSuite.Add(new TestCaseData(c).SetName(prefix + "GoodDefault")); + } + + { + TlsTestConfig c = CreateDtlsTestConfig(version); + c.serverCertReq = C.SERVER_CERT_REQ_NONE; + + testSuite.Add(new TestCaseData(c).SetName(prefix + "GoodNoCertReq")); + } + + { + TlsTestConfig c = CreateDtlsTestConfig(version); + c.clientAuth = C.CLIENT_AUTH_NONE; + + testSuite.Add(new TestCaseData(c).SetName(prefix + "GoodOptionalCertReqDeclined")); + } + } + + private static TlsTestConfig CreateDtlsTestConfig(ProtocolVersion version) + { + TlsTestConfig c = new TlsTestConfig(); + c.clientMinimumVersion = ProtocolVersion.DTLSv10; + /* + * TODO We'd like to just set the offer version to DTLSv12, but there is a known issue with + * overly-restrictive version checks b/w BC DTLS 1.2 client, BC DTLS 1.0 server + */ + c.clientOfferVersion = version; + c.serverMaximumVersion = version; + c.serverMinimumVersion = ProtocolVersion.DTLSv10; + return c; + } + } +} diff --git a/crypto/test/src/crypto/tls/test/LoggingDatagramTransport.cs b/crypto/test/src/crypto/tls/test/LoggingDatagramTransport.cs new file mode 100644 index 000000000..a26c5bdbf --- /dev/null +++ b/crypto/test/src/crypto/tls/test/LoggingDatagramTransport.cs @@ -0,0 +1,86 @@ +using System; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + public class LoggingDatagramTransport + : DatagramTransport + { + private static readonly string HEX_CHARS = "0123456789ABCDEF"; + + private readonly DatagramTransport transport; + private readonly TextWriter output; + private readonly long launchTimestamp; + + public LoggingDatagramTransport(DatagramTransport transport, TextWriter output) + { + this.transport = transport; + this.output = output; + this.launchTimestamp = DateTimeUtilities.CurrentUnixMs(); + } + + public virtual int GetReceiveLimit() + { + return transport.GetReceiveLimit(); + } + + public virtual int GetSendLimit() + { + return transport.GetSendLimit(); + } + + public virtual int Receive(byte[] buf, int off, int len, int waitMillis) + { + int length = transport.Receive(buf, off, len, waitMillis); + if (length >= 0) + { + DumpDatagram("Received", buf, off, length); + } + return length; + } + + public virtual void Send(byte[] buf, int off, int len) + { + DumpDatagram("Sending", buf, off, len); + transport.Send(buf, off, len); + } + + public virtual void Close() + { + } + + private void DumpDatagram(string verb, byte[] buf, int off, int len) + { + long timestamp = DateTimeUtilities.CurrentUnixMs() - launchTimestamp; + StringBuilder sb = new StringBuilder("(+" + timestamp + "ms) " + verb + " " + len + " byte datagram:"); + for (int pos = 0; pos < len; ++pos) + { + if (pos % 16 == 0) + { + sb.Append(Environment.NewLine); + sb.Append(" "); + } + else if (pos % 16 == 8) + { + sb.Append('-'); + } + else + { + sb.Append(' '); + } + int val = buf[off + pos] & 0xFF; + sb.Append(HEX_CHARS[val >> 4]); + sb.Append(HEX_CHARS[val & 0xF]); + } + Dump(sb.ToString()); + } + + private void Dump(string s) + { + lock (this) output.WriteLine(s); + } + } +} diff --git a/crypto/test/src/crypto/tls/test/MockDatagramAssociation.cs b/crypto/test/src/crypto/tls/test/MockDatagramAssociation.cs new file mode 100644 index 000000000..48df36ca9 --- /dev/null +++ b/crypto/test/src/crypto/tls/test/MockDatagramAssociation.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections; +using System.IO; +using System.Net; +using System.Threading; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + public class MockDatagramAssociation + { + private int mtu; + private MockDatagramTransport client, server; + + public MockDatagramAssociation(int mtu) + { + this.mtu = mtu; + + IList clientQueue = new ArrayList(); + IList serverQueue = new ArrayList(); + + this.client = new MockDatagramTransport(this, clientQueue, serverQueue); + this.server = new MockDatagramTransport(this, serverQueue, clientQueue); + } + + public virtual DatagramTransport Client + { + get { return client; } + } + + public virtual DatagramTransport Server + { + get { return server; } + } + + private class MockDatagramTransport + : DatagramTransport + { + private readonly MockDatagramAssociation mOuter; + + private IList receiveQueue, sendQueue; + + internal MockDatagramTransport(MockDatagramAssociation outer, IList receiveQueue, IList sendQueue) + { + this.mOuter = outer; + this.receiveQueue = receiveQueue; + this.sendQueue = sendQueue; + } + + public virtual int GetReceiveLimit() + { + return mOuter.mtu; + } + + public virtual int GetSendLimit() + { + return mOuter.mtu; + } + + public virtual int Receive(byte[] buf, int off, int len, int waitMillis) + { + lock (receiveQueue) + { + if (receiveQueue.Count < 1) + { + try + { + Monitor.Wait(receiveQueue, waitMillis); + } + catch (ThreadInterruptedException) + { + // TODO Keep waiting until full wait expired? + } + if (receiveQueue.Count < 1) + { + return -1; + } + } + byte[] packet = (byte[])receiveQueue[0]; + receiveQueue.RemoveAt(0); + int copyLength = System.Math.Min(len, packet.Length); + Array.Copy(packet, 0, buf, off, copyLength); + return copyLength; + } + } + + public virtual void Send(byte[] buf, int off, int len) + { + if (len > mOuter.mtu) + { + // TODO Simulate rejection? + } + + byte[] packet = Arrays.CopyOfRange(buf, off, off + len); + + lock (sendQueue) + { + sendQueue.Add(packet); + Monitor.PulseAll(sendQueue); + } + } + + public virtual void Close() + { + // TODO? + } + } + } +} diff --git a/crypto/test/src/crypto/tls/test/MockDtlsClient.cs b/crypto/test/src/crypto/tls/test/MockDtlsClient.cs new file mode 100644 index 000000000..e3c604db7 --- /dev/null +++ b/crypto/test/src/crypto/tls/test/MockDtlsClient.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + public class MockDtlsClient + : DefaultTlsClient + { + protected TlsSession mSession; + + public MockDtlsClient(TlsSession session) + { + this.mSession = session; + } + + public override TlsSession GetSessionToResume() + { + return this.mSession; + } + + public override void NotifyAlertRaised(byte alertLevel, byte alertDescription, string message, Exception cause) + { + TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; + output.WriteLine("DTLS client raised alert: " + AlertLevel.GetText(alertLevel) + + ", " + AlertDescription.GetText(alertDescription)); + if (message != null) + { + output.WriteLine("> " + message); + } + if (cause != null) + { + output.WriteLine(cause); + } + } + + public override void NotifyAlertReceived(byte alertLevel, byte alertDescription) + { + TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; + output.WriteLine("DTLS client received alert: " + AlertLevel.GetText(alertLevel) + + ", " + AlertDescription.GetText(alertDescription)); + } + + public override ProtocolVersion ClientVersion + { + get { return ProtocolVersion.DTLSv12; } + } + + public override ProtocolVersion MinimumVersion + { + get { return ProtocolVersion.DTLSv10; } + } + + //public override int[] GetCipherSuites() + //{ + // return Arrays.Concatenate(base.GetCipherSuites(), + // new int[] + // { + // CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + // CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1, + // CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1, + // CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1, + // CipherSuite.TLS_RSA_WITH_SALSA20_SHA1, + // }); + //} + + public override IDictionary GetClientExtensions() + { + IDictionary clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(base.GetClientExtensions()); + TlsExtensionsUtilities.AddEncryptThenMacExtension(clientExtensions); + TlsExtensionsUtilities.AddExtendedMasterSecretExtension(clientExtensions); + TlsExtensionsUtilities.AddMaxFragmentLengthExtension(clientExtensions, MaxFragmentLength.pow2_9); + TlsExtensionsUtilities.AddTruncatedHMacExtension(clientExtensions); + return clientExtensions; + } + + public override void NotifyServerVersion(ProtocolVersion serverVersion) + { + base.NotifyServerVersion(serverVersion); + + Console.WriteLine("Negotiated " + serverVersion); + } + + public override TlsAuthentication GetAuthentication() + { + return new MyTlsAuthentication(mContext); + } + + public override void NotifyHandshakeComplete() + { + base.NotifyHandshakeComplete(); + + TlsSession newSession = mContext.ResumableSession; + if (newSession != null) + { + byte[] newSessionID = newSession.SessionID; + string hex = Hex.ToHexString(newSessionID); + + if (this.mSession != null && Arrays.AreEqual(this.mSession.SessionID, newSessionID)) + { + Console.WriteLine("Resumed session: " + hex); + } + else + { + Console.WriteLine("Established session: " + hex); + } + + this.mSession = newSession; + } + } + + internal class MyTlsAuthentication + : TlsAuthentication + { + private readonly TlsContext mContext; + + internal MyTlsAuthentication(TlsContext context) + { + this.mContext = context; + } + + public virtual void NotifyServerCertificate(Certificate serverCertificate) + { + X509CertificateStructure[] chain = serverCertificate.GetCertificateList(); + Console.WriteLine("DTLS client received server certificate chain of length " + chain.Length); + for (int i = 0; i != chain.Length; i++) + { + X509CertificateStructure entry = chain[i]; + // TODO Create fingerprint based on certificate signature algorithm digest + Console.WriteLine(" fingerprint:SHA-256 " + TlsTestUtilities.Fingerprint(entry) + " (" + + entry.Subject + ")"); + } + } + + public virtual TlsCredentials GetClientCredentials(CertificateRequest certificateRequest) + { + byte[] certificateTypes = certificateRequest.CertificateTypes; + if (certificateTypes == null || !Arrays.Contains(certificateTypes, ClientCertificateType.rsa_sign)) + return null; + + return TlsTestUtilities.LoadSignerCredentials(mContext, certificateRequest.SupportedSignatureAlgorithms, + SignatureAlgorithm.rsa, "x509-client.pem", "x509-client-key.pem"); + } + }; + } +} diff --git a/crypto/test/src/crypto/tls/test/MockDtlsServer.cs b/crypto/test/src/crypto/tls/test/MockDtlsServer.cs new file mode 100644 index 000000000..19062181b --- /dev/null +++ b/crypto/test/src/crypto/tls/test/MockDtlsServer.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + public class MockDtlsServer + : DefaultTlsServer + { + public override void NotifyAlertRaised(byte alertLevel, byte alertDescription, string message, Exception cause) + { + TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; + output.WriteLine("DTLS server raised alert: " + AlertLevel.GetText(alertLevel) + + ", " + AlertDescription.GetText(alertDescription)); + if (message != null) + { + output.WriteLine("> " + message); + } + if (cause != null) + { + output.WriteLine(cause); + } + } + + public override void NotifyAlertReceived(byte alertLevel, byte alertDescription) + { + TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; + output.WriteLine("DTLS server received alert: " + AlertLevel.GetText(alertLevel) + + ", " + AlertDescription.GetText(alertDescription)); + } + + protected override int[] GetCipherSuites() + { + return Arrays.Concatenate(base.GetCipherSuites(), + new int[] + { + CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1, + CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1, + CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1, + CipherSuite.TLS_RSA_WITH_SALSA20_SHA1, + }); + } + + public override CertificateRequest GetCertificateRequest() + { + byte[] certificateTypes = new byte[]{ ClientCertificateType.rsa_sign, + ClientCertificateType.dss_sign, ClientCertificateType.ecdsa_sign }; + + IList serverSigAlgs = null; + if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(mServerVersion)) + { + serverSigAlgs = TlsUtilities.GetDefaultSupportedSignatureAlgorithms(); + } + + IList certificateAuthorities = new ArrayList(); + certificateAuthorities.Add(TlsTestUtilities.LoadCertificateResource("x509-ca.pem").Subject); + + return new CertificateRequest(certificateTypes, serverSigAlgs, certificateAuthorities); + } + + public override void NotifyClientCertificate(Certificate clientCertificate) + { + X509CertificateStructure[] chain = clientCertificate.GetCertificateList(); + Console.WriteLine("DTLS server received client certificate chain of length " + chain.Length); + for (int i = 0; i != chain.Length; i++) + { + X509CertificateStructure entry = chain[i]; + // TODO Create fingerprint based on certificate signature algorithm digest + Console.WriteLine(" fingerprint:SHA-256 " + TlsTestUtilities.Fingerprint(entry) + " (" + + entry.Subject + ")"); + } + } + + protected override ProtocolVersion MaximumVersion + { + get { return ProtocolVersion.DTLSv12; } + } + + protected override ProtocolVersion MinimumVersion + { + get { return ProtocolVersion.DTLSv10; } + } + + protected override TlsEncryptionCredentials GetRsaEncryptionCredentials() + { + return TlsTestUtilities.LoadEncryptionCredentials(mContext, new string[] { "x509-server.pem", "x509-ca.pem" }, + "x509-server-key.pem"); + } + + protected override TlsSignerCredentials GetRsaSignerCredentials() + { + return TlsTestUtilities.LoadSignerCredentials(mContext, mSupportedSignatureAlgorithms, SignatureAlgorithm.rsa, + "x509-server.pem", "x509-server-key.pem"); + } + } +} diff --git a/crypto/test/src/crypto/tls/test/MockPskTlsClient.cs b/crypto/test/src/crypto/tls/test/MockPskTlsClient.cs new file mode 100644 index 000000000..dfc0e93a0 --- /dev/null +++ b/crypto/test/src/crypto/tls/test/MockPskTlsClient.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + internal class MockPskTlsClient + : PskTlsClient + { + internal TlsSession mSession; + + internal MockPskTlsClient(TlsSession session) + : this(session, new BasicTlsPskIdentity("client", new byte[16])) + { + } + + internal MockPskTlsClient(TlsSession session, TlsPskIdentity pskIdentity) + : base(pskIdentity) + { + this.mSession = session; + } + + public override TlsSession GetSessionToResume() + { + return this.mSession; + } + + public override void NotifyAlertRaised(byte alertLevel, byte alertDescription, string message, Exception cause) + { + TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; + output.WriteLine("TLS-PSK client raised alert: " + AlertLevel.GetText(alertLevel) + + ", " + AlertDescription.GetText(alertDescription)); + if (message != null) + { + output.WriteLine("> " + message); + } + if (cause != null) + { + output.WriteLine(cause); + } + } + + public override void NotifyAlertReceived(byte alertLevel, byte alertDescription) + { + TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; + output.WriteLine("TLS-PSK client received alert: " + AlertLevel.GetText(alertLevel) + + ", " + AlertDescription.GetText(alertDescription)); + } + + public override void NotifyHandshakeComplete() + { + base.NotifyHandshakeComplete(); + + TlsSession newSession = mContext.ResumableSession; + if (newSession != null) + { + byte[] newSessionID = newSession.SessionID; + string hex = Hex.ToHexString(newSessionID); + + if (this.mSession != null && Arrays.AreEqual(this.mSession.SessionID, newSessionID)) + { + Console.WriteLine("Resumed session: " + hex); + } + else + { + Console.WriteLine("Established session: " + hex); + } + + this.mSession = newSession; + } + } + + public override int[] GetCipherSuites() + { + return new int[]{ CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, + CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, + CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA }; + } + + public override ProtocolVersion MinimumVersion + { + get { return ProtocolVersion.TLSv12; } + } + + public override IDictionary GetClientExtensions() + { + IDictionary clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(base.GetClientExtensions()); + TlsExtensionsUtilities.AddEncryptThenMacExtension(clientExtensions); + return clientExtensions; + } + + public override void NotifyServerVersion(ProtocolVersion serverVersion) + { + base.NotifyServerVersion(serverVersion); + + Console.WriteLine("TLS-PSK client negotiated " + serverVersion); + } + + public override TlsAuthentication GetAuthentication() + { + return new MyTlsAuthentication(mContext); + } + + internal class MyTlsAuthentication + : ServerOnlyTlsAuthentication + { + private readonly TlsContext mContext; + + internal MyTlsAuthentication(TlsContext context) + { + this.mContext = context; + } + + public override void NotifyServerCertificate(Certificate serverCertificate) + { + X509CertificateStructure[] chain = serverCertificate.GetCertificateList(); + Console.WriteLine("TLS-PSK client received server certificate chain of length " + chain.Length); + for (int i = 0; i != chain.Length; i++) + { + X509CertificateStructure entry = chain[i]; + // TODO Create fingerprint based on certificate signature algorithm digest + Console.WriteLine(" fingerprint:SHA-256 " + TlsTestUtilities.Fingerprint(entry) + " (" + + entry.Subject + ")"); + } + } + }; + } +} diff --git a/crypto/test/src/crypto/tls/test/MockPskTlsServer.cs b/crypto/test/src/crypto/tls/test/MockPskTlsServer.cs new file mode 100644 index 000000000..7394a2077 --- /dev/null +++ b/crypto/test/src/crypto/tls/test/MockPskTlsServer.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + internal class MockPskTlsServer + : PskTlsServer + { + internal MockPskTlsServer() + : base(new MyIdentityManager()) + { + } + + public override void NotifyAlertRaised(byte alertLevel, byte alertDescription, string message, Exception cause) + { + TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; + output.WriteLine("TLS-PSK server raised alert: " + AlertLevel.GetText(alertLevel) + + ", " + AlertDescription.GetText(alertDescription)); + if (message != null) + { + output.WriteLine("> " + message); + } + if (cause != null) + { + output.WriteLine(cause); + } + } + + public override void NotifyAlertReceived(byte alertLevel, byte alertDescription) + { + TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; + output.WriteLine("TLS-PSK server received alert: " + AlertLevel.GetText(alertLevel) + + ", " + AlertDescription.GetText(alertDescription)); + } + + public override void NotifyHandshakeComplete() + { + base.NotifyHandshakeComplete(); + + byte[] pskIdentity = mContext.SecurityParameters.PskIdentity; + if (pskIdentity != null) + { + string name = Strings.FromUtf8ByteArray(pskIdentity); + Console.WriteLine("TLS-PSK server completed handshake for PSK identity: " + name); + } + } + + protected override int[] GetCipherSuites() + { + return new int[]{ CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, + CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, + CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA }; + } + + protected override ProtocolVersion MaximumVersion + { + get { return ProtocolVersion.TLSv12; } + } + + protected override ProtocolVersion MinimumVersion + { + get { return ProtocolVersion.TLSv12; } + } + + public override ProtocolVersion GetServerVersion() + { + ProtocolVersion serverVersion = base.GetServerVersion(); + + Console.WriteLine("TLS-PSK server negotiated " + serverVersion); + + return serverVersion; + } + + protected override TlsEncryptionCredentials GetRsaEncryptionCredentials() + { + return TlsTestUtilities.LoadEncryptionCredentials(mContext, new string[]{"x509-server.pem", "x509-ca.pem"}, + "x509-server-key.pem"); + } + + internal class MyIdentityManager + : TlsPskIdentityManager + { + public virtual byte[] GetHint() + { + return Strings.ToUtf8ByteArray("hint"); + } + + public virtual byte[] GetPsk(byte[] identity) + { + if (identity != null) + { + string name = Strings.FromUtf8ByteArray(identity); + if (name.Equals("client")) + { + return new byte[16]; + } + } + return null; + } + } + } +} diff --git a/crypto/test/src/crypto/tls/test/MockSrpTlsClient.cs b/crypto/test/src/crypto/tls/test/MockSrpTlsClient.cs new file mode 100644 index 000000000..8a6b9f496 --- /dev/null +++ b/crypto/test/src/crypto/tls/test/MockSrpTlsClient.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + internal class MockSrpTlsClient + : SrpTlsClient + { + internal TlsSession mSession; + + internal MockSrpTlsClient(TlsSession session, byte[] identity, byte[] password) + : base(identity, password) + { + this.mSession = session; + } + + public override TlsSession GetSessionToResume() + { + return this.mSession; + } + + public override void NotifyAlertRaised(byte alertLevel, byte alertDescription, string message, Exception cause) + { + TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; + output.WriteLine("TLS-SRP client raised alert: " + AlertLevel.GetText(alertLevel) + + ", " + AlertDescription.GetText(alertDescription)); + if (message != null) + { + output.WriteLine("> " + message); + } + if (cause != null) + { + output.WriteLine(cause); + } + } + + public override void NotifyAlertReceived(byte alertLevel, byte alertDescription) + { + TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; + output.WriteLine("TLS-SRP client received alert: " + AlertLevel.GetText(alertLevel) + + ", " + AlertDescription.GetText(alertDescription)); + } + + public override void NotifyHandshakeComplete() + { + base.NotifyHandshakeComplete(); + + TlsSession newSession = mContext.ResumableSession; + if (newSession != null) + { + byte[] newSessionID = newSession.SessionID; + string hex = Hex.ToHexString(newSessionID); + + if (this.mSession != null && Arrays.AreEqual(this.mSession.SessionID, newSessionID)) + { + Console.WriteLine("Resumed session: " + hex); + } + else + { + Console.WriteLine("Established session: " + hex); + } + + this.mSession = newSession; + } + } + + public override ProtocolVersion MinimumVersion + { + get { return ProtocolVersion.TLSv12; } + } + + public override IDictionary GetClientExtensions() + { + IDictionary clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(base.GetClientExtensions()); + TlsExtensionsUtilities.AddEncryptThenMacExtension(clientExtensions); + return clientExtensions; + } + + public override void NotifyServerVersion(ProtocolVersion serverVersion) + { + base.NotifyServerVersion(serverVersion); + + Console.WriteLine("TLS-SRP client negotiated " + serverVersion); + } + + public override TlsAuthentication GetAuthentication() + { + return new MyTlsAuthentication(mContext); + } + + internal class MyTlsAuthentication + : ServerOnlyTlsAuthentication + { + private readonly TlsContext mContext; + + internal MyTlsAuthentication(TlsContext context) + { + this.mContext = context; + } + + public override void NotifyServerCertificate(Certificate serverCertificate) + { + X509CertificateStructure[] chain = serverCertificate.GetCertificateList(); + Console.WriteLine("TLS-SRP client received server certificate chain of length " + chain.Length); + for (int i = 0; i != chain.Length; i++) + { + X509CertificateStructure entry = chain[i]; + // TODO Create fingerprint based on certificate signature algorithm digest + Console.WriteLine(" fingerprint:SHA-256 " + TlsTestUtilities.Fingerprint(entry) + " (" + + entry.Subject + ")"); + } + } + }; + } +} diff --git a/crypto/test/src/crypto/tls/test/MockSrpTlsServer.cs b/crypto/test/src/crypto/tls/test/MockSrpTlsServer.cs new file mode 100644 index 000000000..c15f63e0b --- /dev/null +++ b/crypto/test/src/crypto/tls/test/MockSrpTlsServer.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Crypto.Agreement.Srp; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + internal class MockSrpTlsServer + : SrpTlsServer + { + internal static readonly Srp6GroupParameters TEST_GROUP = Srp6StandardGroups.rfc5054_1024; + internal static readonly byte[] TEST_IDENTITY = Strings.ToUtf8ByteArray("client"); + internal static readonly byte[] TEST_PASSWORD = Strings.ToUtf8ByteArray("password"); + internal static readonly byte[] TEST_SALT = Strings.ToUtf8ByteArray("salt"); + internal static readonly byte[] TEST_SEED_KEY = Strings.ToUtf8ByteArray("seed_key"); + + internal MockSrpTlsServer() + : base(new MyIdentityManager()) + { + } + + public override void NotifyAlertRaised(byte alertLevel, byte alertDescription, string message, Exception cause) + { + TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; + output.WriteLine("TLS-SRP server raised alert: " + AlertLevel.GetText(alertLevel) + + ", " + AlertDescription.GetText(alertDescription)); + if (message != null) + { + output.WriteLine("> " + message); + } + if (cause != null) + { + output.WriteLine(cause); + } + } + + public override void NotifyAlertReceived(byte alertLevel, byte alertDescription) + { + TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; + output.WriteLine("TLS-SRP server received alert: " + AlertLevel.GetText(alertLevel) + + ", " + AlertDescription.GetText(alertDescription)); + } + + public override void NotifyHandshakeComplete() + { + base.NotifyHandshakeComplete(); + + byte[] srpIdentity = mContext.SecurityParameters.SrpIdentity; + if (srpIdentity != null) + { + string name = Strings.FromUtf8ByteArray(srpIdentity); + Console.WriteLine("TLS-SRP server completed handshake for SRP identity: " + name); + } + } + + protected override ProtocolVersion MaximumVersion + { + get { return ProtocolVersion.TLSv12; } + } + + protected override ProtocolVersion MinimumVersion + { + get { return ProtocolVersion.TLSv12; } + } + + public override ProtocolVersion GetServerVersion() + { + ProtocolVersion serverVersion = base.GetServerVersion(); + + Console.WriteLine("TLS-SRP server negotiated " + serverVersion); + + return serverVersion; + } + + protected override TlsSignerCredentials GetDsaSignerCredentials() + { + return TlsTestUtilities.LoadSignerCredentials(mContext, mSupportedSignatureAlgorithms, SignatureAlgorithm.dsa, + "x509-server-dsa.pem", "x509-server-key-dsa.pem"); + } + + protected override TlsSignerCredentials GetRsaSignerCredentials() + { + return TlsTestUtilities.LoadSignerCredentials(mContext, mSupportedSignatureAlgorithms, SignatureAlgorithm.rsa, + "x509-server.pem", "x509-server-key.pem"); + } + + internal class MyIdentityManager + : TlsSrpIdentityManager + { + protected SimulatedTlsSrpIdentityManager unknownIdentityManager = SimulatedTlsSrpIdentityManager.GetRfc5054Default( + TEST_GROUP, TEST_SEED_KEY); + + public virtual TlsSrpLoginParameters GetLoginParameters(byte[] identity) + { + if (Arrays.AreEqual(TEST_IDENTITY, identity)) + { + Srp6VerifierGenerator verifierGenerator = new Srp6VerifierGenerator(); + verifierGenerator.Init(TEST_GROUP, TlsUtilities.CreateHash(HashAlgorithm.sha1)); + + BigInteger verifier = verifierGenerator.GenerateVerifier(TEST_SALT, identity, TEST_PASSWORD); + + return new TlsSrpLoginParameters(TEST_GROUP, verifier, TEST_SALT); + } + + return unknownIdentityManager.GetLoginParameters(identity); + } + } + } +} diff --git a/crypto/test/src/crypto/tls/test/MockTlsClient.cs b/crypto/test/src/crypto/tls/test/MockTlsClient.cs index a458e32e6..7c1198632 100644 --- a/crypto/test/src/crypto/tls/test/MockTlsClient.cs +++ b/crypto/test/src/crypto/tls/test/MockTlsClient.cs @@ -45,25 +45,24 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests + ", " + AlertDescription.GetText(alertDescription)); } - public override int[] GetCipherSuites() - { - return Arrays.Concatenate(base.GetCipherSuites(), - new int[] - { - CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1, - CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1, - CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1, - CipherSuite.TLS_RSA_WITH_SALSA20_SHA1, - }); - } + //public override int[] GetCipherSuites() + //{ + // return Arrays.Concatenate(base.GetCipherSuites(), + // new int[] + // { + // CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + // CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1, + // CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1, + // CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1, + // CipherSuite.TLS_RSA_WITH_SALSA20_SHA1, + // }); + //} public override IDictionary GetClientExtensions() { IDictionary clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(base.GetClientExtensions()); TlsExtensionsUtilities.AddEncryptThenMacExtension(clientExtensions); - // TODO[draft-ietf-tls-session-hash-01] Enable once code-point assigned (only for compatible server though) -// TlsExtensionsUtilities.AddExtendedMasterSecretExtension(clientExtensions); + TlsExtensionsUtilities.AddExtendedMasterSecretExtension(clientExtensions); TlsExtensionsUtilities.AddMaxFragmentLengthExtension(clientExtensions, MaxFragmentLength.pow2_9); TlsExtensionsUtilities.AddTruncatedHMacExtension(clientExtensions); return clientExtensions; @@ -121,8 +120,8 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests for (int i = 0; i != chain.Length; i++) { X509CertificateStructure entry = chain[i]; - // TODO Create Fingerprint based on certificate signature algorithm digest - Console.WriteLine(" Fingerprint:SHA-256 " + TlsTestUtilities.Fingerprint(entry) + " (" + // TODO Create fingerprint based on certificate signature algorithm digest + Console.WriteLine(" fingerprint:SHA-256 " + TlsTestUtilities.Fingerprint(entry) + " (" + entry.Subject + ")"); } } @@ -133,27 +132,8 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests if (certificateTypes == null || !Arrays.Contains(certificateTypes, ClientCertificateType.rsa_sign)) return null; - SignatureAndHashAlgorithm signatureAndHashAlgorithm = null; - IList sigAlgs = certificateRequest.SupportedSignatureAlgorithms; - if (sigAlgs != null) - { - foreach (SignatureAndHashAlgorithm sigAlg in sigAlgs) - { - if (sigAlg.Signature == SignatureAlgorithm.rsa) - { - signatureAndHashAlgorithm = sigAlg; - break; - } - } - - if (signatureAndHashAlgorithm == null) - { - return null; - } - } - - return TlsTestUtilities.LoadSignerCredentials(mContext, new string[] { "x509-client.pem", "x509-ca.pem" }, - "x509-client-key.pem", signatureAndHashAlgorithm); + return TlsTestUtilities.LoadSignerCredentials(mContext, certificateRequest.SupportedSignatureAlgorithms, + SignatureAlgorithm.rsa, "x509-client.pem", "x509-client-key.pem"); } }; } diff --git a/crypto/test/src/crypto/tls/test/MockTlsServer.cs b/crypto/test/src/crypto/tls/test/MockTlsServer.cs index 14d6b9839..8fce95d63 100644 --- a/crypto/test/src/crypto/tls/test/MockTlsServer.cs +++ b/crypto/test/src/crypto/tls/test/MockTlsServer.cs @@ -61,29 +61,19 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests public override CertificateRequest GetCertificateRequest() { - IList serverSigAlgs = null; + byte[] certificateTypes = new byte[]{ ClientCertificateType.rsa_sign, + ClientCertificateType.dss_sign, ClientCertificateType.ecdsa_sign }; + IList serverSigAlgs = null; if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(mServerVersion)) { - byte[] hashAlgorithms = new byte[]{ HashAlgorithm.sha512, HashAlgorithm.sha384, HashAlgorithm.sha256, - HashAlgorithm.sha224, HashAlgorithm.sha1 }; - byte[] signatureAlgorithms = new byte[]{ SignatureAlgorithm.rsa }; - - serverSigAlgs = new ArrayList(); - for (int i = 0; i < hashAlgorithms.Length; ++i) - { - for (int j = 0; j < signatureAlgorithms.Length; ++j) - { - serverSigAlgs.Add(new SignatureAndHashAlgorithm(hashAlgorithms[i], - signatureAlgorithms[j])); - } - } + serverSigAlgs = TlsUtilities.GetDefaultSupportedSignatureAlgorithms(); } IList certificateAuthorities = new ArrayList(); certificateAuthorities.Add(TlsTestUtilities.LoadCertificateResource("x509-ca.pem").Subject); - return new CertificateRequest(new byte[]{ ClientCertificateType.rsa_sign }, serverSigAlgs, certificateAuthorities); + return new CertificateRequest(certificateTypes, serverSigAlgs, certificateAuthorities); } public override void NotifyClientCertificate(Certificate clientCertificate) @@ -101,37 +91,14 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests protected override TlsEncryptionCredentials GetRsaEncryptionCredentials() { - return TlsTestUtilities.LoadEncryptionCredentials(mContext, new string[]{"x509-server.pem", "x509-ca.pem"}, + return TlsTestUtilities.LoadEncryptionCredentials(mContext, new string[]{ "x509-server.pem", "x509-ca.pem" }, "x509-server-key.pem"); } protected override TlsSignerCredentials GetRsaSignerCredentials() { - /* - * TODO Note that this code fails to provide default value for the client supported - * algorithms if it wasn't sent. - */ - SignatureAndHashAlgorithm signatureAndHashAlgorithm = null; - IList sigAlgs = mSupportedSignatureAlgorithms; - if (sigAlgs != null) - { - foreach (SignatureAndHashAlgorithm sigAlg in sigAlgs) - { - if (sigAlg.Signature == SignatureAlgorithm.rsa) - { - signatureAndHashAlgorithm = sigAlg; - break; - } - } - - if (signatureAndHashAlgorithm == null) - { - return null; - } - } - - return TlsTestUtilities.LoadSignerCredentials(mContext, new string[]{"x509-server.pem", "x509-ca.pem"}, - "x509-server-key.pem", signatureAndHashAlgorithm); + return TlsTestUtilities.LoadSignerCredentials(mContext, mSupportedSignatureAlgorithms, SignatureAlgorithm.rsa, + "x509-server.pem", "x509-server-key.pem"); } } } diff --git a/crypto/test/src/crypto/tls/test/NetworkStream.cs b/crypto/test/src/crypto/tls/test/NetworkStream.cs new file mode 100644 index 000000000..04de81e13 --- /dev/null +++ b/crypto/test/src/crypto/tls/test/NetworkStream.cs @@ -0,0 +1,101 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + internal class NetworkStream + : Stream + { + private readonly Stream mInner; + private bool mClosed = false; + + internal NetworkStream(Stream inner) + { + this.mInner = inner; + } + + internal virtual bool IsClosed + { + get { lock (this) return mClosed; } + } + + public override bool CanRead + { + get { return mInner.CanRead; } + } + + public override bool CanSeek + { + get { return mInner.CanSeek; } + } + + public override bool CanWrite + { + get { return mInner.CanWrite; } + } + + public override void Close() + { + lock (this) mClosed = true; + } + + public override void Flush() + { + mInner.Flush(); + } + + public override long Length + { + get { return mInner.Length; } + } + + public override long Position + { + get { return mInner.Position; } + set { mInner.Position = value; } + } + + public override long Seek(long offset, SeekOrigin origin) + { + return mInner.Seek(offset, origin); + } + + public override void SetLength(long value) + { + mInner.SetLength(value); + } + + public override int Read(byte[] buffer, int offset, int count) + { + CheckNotClosed(); + return mInner.Read(buffer, offset, count); + } + + public override int ReadByte() + { + CheckNotClosed(); + return mInner.ReadByte(); + } + + public override void Write(byte[] buf, int off, int len) + { + CheckNotClosed(); + mInner.Write(buf, off, len); + } + + public override void WriteByte(byte value) + { + CheckNotClosed(); + mInner.WriteByte(value); + } + + private void CheckNotClosed() + { + lock (this) + { + if (mClosed) + throw new ObjectDisposedException(this.GetType().Name); + } + } + } +} diff --git a/crypto/test/src/crypto/tls/test/PipedStream.cs b/crypto/test/src/crypto/tls/test/PipedStream.cs new file mode 100644 index 000000000..6b2c15059 --- /dev/null +++ b/crypto/test/src/crypto/tls/test/PipedStream.cs @@ -0,0 +1,134 @@ +using System; +using System.IO; +using System.Threading; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + internal class PipedStream + : Stream + { + private readonly MemoryStream mBuf = new MemoryStream(); + private bool mClosed = false; + + private PipedStream mOther = null; + private long mReadPos = 0; + + internal PipedStream() + { + } + + internal PipedStream(PipedStream other) + { + lock (other) + { + this.mOther = other; + other.mOther = this; + } + } + + public override bool CanRead + { + get { return true; } + } + + public override bool CanSeek + { + get { return false; } + } + + public override bool CanWrite + { + get { return true; } + } + + public override void Close() + { + lock (this) + { + mClosed = true; + Monitor.PulseAll(this); + } + } + + public override void Flush() + { + } + + public override long Length + { + get { throw new NotImplementedException(); } + } + + public override long Position + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotImplementedException(); + } + + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + lock (mOther) + { + WaitForData(); + int len = (int)System.Math.Min(count, mOther.mBuf.Position - mReadPos); + Array.Copy(mOther.mBuf.GetBuffer(), mReadPos, buffer, offset, len); + mReadPos += len; + return len; + } + } + + public override int ReadByte() + { + lock (mOther) + { + WaitForData(); + bool eof = (mReadPos >= mOther.mBuf.Position); + return eof ? -1 : mOther.mBuf.GetBuffer()[mReadPos++]; + } + } + + public override void Write(byte[] buf, int off, int len) + { + lock (this) + { + CheckOpen(); + mBuf.Write(buf, off, len); + Monitor.PulseAll(this); + } + } + + public override void WriteByte(byte value) + { + lock (this) + { + CheckOpen(); + mBuf.WriteByte(value); + Monitor.PulseAll(mBuf); + } + } + + private void CheckOpen() + { + if (mClosed) + throw new ObjectDisposedException(this.GetType().Name); + } + + private void WaitForData() + { + while (mReadPos >= mOther.mBuf.Position && !mOther.mClosed) + { + Monitor.Wait(mOther); + } + } + } +} diff --git a/crypto/test/src/crypto/tls/test/PskTlsClientTest.cs b/crypto/test/src/crypto/tls/test/PskTlsClientTest.cs new file mode 100644 index 000000000..7072c7105 --- /dev/null +++ b/crypto/test/src/crypto/tls/test/PskTlsClientTest.cs @@ -0,0 +1,79 @@ +using System; +using System.IO; +using System.Net.Sockets; +using System.Text; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + /** + * A simple test designed to conduct a TLS handshake with an external TLS server. + * <p> + * Please refer to GnuTLSSetup.html or OpenSSLSetup.html (under 'docs'), and x509-*.pem files in + * this package (under 'src/test/resources') for help configuring an external TLS server. + * </p><p> + * In both cases, extra options are required to enable PSK ciphersuites and configure identities/keys. + * </p> + */ + public class PskTlsClientTest + { + private static readonly SecureRandom secureRandom = new SecureRandom(); + + public static void Main(string[] args) + { + string hostname = "localhost"; + int port = 5556; + + long time1 = DateTime.UtcNow.Ticks; + + /* + * Note: This is the default PSK identity for 'openssl s_server' testing, the server must be + * started with "-psk 6161616161" to make the keys match, and possibly the "-psk_hint" + * option should be present. + */ + string psk_identity = "Client_identity"; + byte[] psk = new byte[]{ 0x61, 0x61, 0x61, 0x61, 0x61 }; + + BasicTlsPskIdentity pskIdentity = new BasicTlsPskIdentity(psk_identity, psk); + + MockPskTlsClient client = new MockPskTlsClient(null, pskIdentity); + TlsClientProtocol protocol = OpenTlsConnection(hostname, port, client); + protocol.Close(); + + long time2 = DateTime.UtcNow.Ticks; + Console.WriteLine("Elapsed 1: " + (time2 - time1)/TimeSpan.TicksPerMillisecond + "ms"); + + client = new MockPskTlsClient(client.GetSessionToResume(), pskIdentity); + protocol = OpenTlsConnection(hostname, port, client); + + long time3 = DateTime.UtcNow.Ticks; + Console.WriteLine("Elapsed 2: " + (time3 - time2)/TimeSpan.TicksPerMillisecond + "ms"); + + byte[] req = Encoding.UTF8.GetBytes("GET / HTTP/1.1\r\n\r\n"); + + Stream tlsStream = protocol.Stream; + tlsStream.Write(req, 0, req.Length); + tlsStream.Flush(); + + StreamReader reader = new StreamReader(tlsStream); + + String line; + while ((line = reader.ReadLine()) != null) + { + Console.WriteLine(">>> " + line); + } + + protocol.Close(); + } + + internal static TlsClientProtocol OpenTlsConnection(string hostname, int port, TlsClient client) + { + TcpClient tcp = new TcpClient(hostname, port); + + TlsClientProtocol protocol = new TlsClientProtocol(tcp.GetStream(), secureRandom); + protocol.Connect(client); + return protocol; + } + } +} diff --git a/crypto/test/src/crypto/tls/test/TlsProtocolTest.cs b/crypto/test/src/crypto/tls/test/TlsProtocolTest.cs new file mode 100644 index 000000000..ba5b90c75 --- /dev/null +++ b/crypto/test/src/crypto/tls/test/TlsProtocolTest.cs @@ -0,0 +1,80 @@ +using System; +using System.IO; +using System.Threading; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +using NUnit.Framework; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + [TestFixture] + public class TlsProtocolTest + { + [Test] + public void TestClientServer() + { + SecureRandom secureRandom = new SecureRandom(); + + PipedStream clientPipe = new PipedStream(); + PipedStream serverPipe = new PipedStream(clientPipe); + + TlsClientProtocol clientProtocol = new TlsClientProtocol(clientPipe, secureRandom); + TlsServerProtocol serverProtocol = new TlsServerProtocol(serverPipe, secureRandom); + + Server server = new Server(serverProtocol); + + Thread serverThread = new Thread(new ThreadStart(server.Run)); + serverThread.Start(); + + MockTlsClient client = new MockTlsClient(null); + clientProtocol.Connect(client); + + // NOTE: Because we write-all before we read-any, this length can't be more than the pipe capacity + int length = 1000; + + byte[] data = new byte[length]; + secureRandom.NextBytes(data); + + Stream output = clientProtocol.Stream; + output.Write(data, 0, data.Length); + + byte[] echo = new byte[data.Length]; + int count = Streams.ReadFully(clientProtocol.Stream, echo); + + Assert.AreEqual(count, data.Length); + Assert.IsTrue(Arrays.AreEqual(data, echo)); + + output.Close(); + + serverThread.Join(); + } + + internal class Server + { + private readonly TlsServerProtocol mServerProtocol; + + internal Server(TlsServerProtocol serverProtocol) + { + this.mServerProtocol = serverProtocol; + } + + public void Run() + { + try + { + MockTlsServer server = new MockTlsServer(); + mServerProtocol.Accept(server); + Streams.PipeAll(mServerProtocol.Stream, mServerProtocol.Stream); + mServerProtocol.Close(); + } + catch (Exception) + { + //throw new RuntimeException(e); + } + } + } + } +} diff --git a/crypto/test/src/crypto/tls/test/TlsPskProtocolTest.cs b/crypto/test/src/crypto/tls/test/TlsPskProtocolTest.cs new file mode 100644 index 000000000..b059bb2cb --- /dev/null +++ b/crypto/test/src/crypto/tls/test/TlsPskProtocolTest.cs @@ -0,0 +1,80 @@ +using System; +using System.IO; +using System.Threading; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +using NUnit.Framework; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + [TestFixture] + public class TlsPskProtocolTest + { + [Test] + public void TestClientServer() + { + SecureRandom secureRandom = new SecureRandom(); + + PipedStream clientPipe = new PipedStream(); + PipedStream serverPipe = new PipedStream(clientPipe); + + TlsClientProtocol clientProtocol = new TlsClientProtocol(clientPipe, secureRandom); + TlsServerProtocol serverProtocol = new TlsServerProtocol(serverPipe, secureRandom); + + Server server = new Server(serverProtocol); + + Thread serverThread = new Thread(new ThreadStart(server.Run)); + serverThread.Start(); + + MockPskTlsClient client = new MockPskTlsClient(null); + clientProtocol.Connect(client); + + // NOTE: Because we write-all before we read-any, this length can't be more than the pipe capacity + int length = 1000; + + byte[] data = new byte[length]; + secureRandom.NextBytes(data); + + Stream output = clientProtocol.Stream; + output.Write(data, 0, data.Length); + + byte[] echo = new byte[data.Length]; + int count = Streams.ReadFully(clientProtocol.Stream, echo); + + Assert.AreEqual(count, data.Length); + Assert.IsTrue(Arrays.AreEqual(data, echo)); + + output.Close(); + + serverThread.Join(); + } + + internal class Server + { + private readonly TlsServerProtocol mServerProtocol; + + internal Server(TlsServerProtocol serverProtocol) + { + this.mServerProtocol = serverProtocol; + } + + public void Run() + { + try + { + MockPskTlsServer server = new MockPskTlsServer(); + mServerProtocol.Accept(server); + Streams.PipeAll(mServerProtocol.Stream, mServerProtocol.Stream); + mServerProtocol.Close(); + } + catch (Exception) + { + //throw new RuntimeException(e); + } + } + } + } +} diff --git a/crypto/test/src/crypto/tls/test/TlsSrpProtocolTest.cs b/crypto/test/src/crypto/tls/test/TlsSrpProtocolTest.cs new file mode 100644 index 000000000..32e126ff2 --- /dev/null +++ b/crypto/test/src/crypto/tls/test/TlsSrpProtocolTest.cs @@ -0,0 +1,80 @@ +using System; +using System.IO; +using System.Threading; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +using NUnit.Framework; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + [TestFixture] + public class TlsSrpProtocolTest + { + [Test] + public void TestClientServer() + { + SecureRandom secureRandom = new SecureRandom(); + + PipedStream clientPipe = new PipedStream(); + PipedStream serverPipe = new PipedStream(clientPipe); + + TlsClientProtocol clientProtocol = new TlsClientProtocol(clientPipe, secureRandom); + TlsServerProtocol serverProtocol = new TlsServerProtocol(serverPipe, secureRandom); + + Server server = new Server(serverProtocol); + + Thread serverThread = new Thread(new ThreadStart(server.Run)); + serverThread.Start(); + + MockSrpTlsClient client = new MockSrpTlsClient(null, MockSrpTlsServer.TEST_IDENTITY, MockSrpTlsServer.TEST_PASSWORD); + clientProtocol.Connect(client); + + // NOTE: Because we write-all before we read-any, this length can't be more than the pipe capacity + int length = 1000; + + byte[] data = new byte[length]; + secureRandom.NextBytes(data); + + Stream output = clientProtocol.Stream; + output.Write(data, 0, data.Length); + + byte[] echo = new byte[data.Length]; + int count = Streams.ReadFully(clientProtocol.Stream, echo); + + Assert.AreEqual(count, data.Length); + Assert.IsTrue(Arrays.AreEqual(data, echo)); + + output.Close(); + + serverThread.Join(); + } + + internal class Server + { + private readonly TlsServerProtocol mServerProtocol; + + internal Server(TlsServerProtocol serverProtocol) + { + this.mServerProtocol = serverProtocol; + } + + public void Run() + { + try + { + MockSrpTlsServer server = new MockSrpTlsServer(); + mServerProtocol.Accept(server); + Streams.PipeAll(mServerProtocol.Stream, mServerProtocol.Stream); + mServerProtocol.Close(); + } + catch (Exception) + { + //throw new RuntimeException(e); + } + } + } + } +} diff --git a/crypto/test/src/crypto/tls/test/TlsTestCase.cs b/crypto/test/src/crypto/tls/test/TlsTestCase.cs new file mode 100644 index 000000000..4b0c12710 --- /dev/null +++ b/crypto/test/src/crypto/tls/test/TlsTestCase.cs @@ -0,0 +1,164 @@ +using System; +using System.IO; +using System.Threading; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +using NUnit.Framework; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + [TestFixture] + public class TlsTestCase + { + private static void CheckTlsVersion(ProtocolVersion version) + { + if (version != null && !version.IsTls) + throw new InvalidOperationException("Non-TLS version"); + } + + [Test, TestCaseSource(typeof(TlsTestSuite), "Suite")] + public void RunTest(TlsTestConfig config) + { + CheckTlsVersion(config.clientMinimumVersion); + CheckTlsVersion(config.clientOfferVersion); + CheckTlsVersion(config.serverMaximumVersion); + CheckTlsVersion(config.serverMinimumVersion); + + SecureRandom secureRandom = new SecureRandom(); + + PipedStream clientPipe = new PipedStream(); + PipedStream serverPipe = new PipedStream(clientPipe); + + NetworkStream clientNet = new NetworkStream(clientPipe); + NetworkStream serverNet = new NetworkStream(serverPipe); + + TlsClientProtocol clientProtocol = new TlsClientProtocol(clientNet, secureRandom); + TlsServerProtocol serverProtocol = new TlsServerProtocol(serverNet, secureRandom); + + TlsTestClientImpl clientImpl = new TlsTestClientImpl(config); + TlsTestServerImpl serverImpl = new TlsTestServerImpl(config); + + Server server = new Server(this, serverProtocol, serverImpl); + + Thread serverThread = new Thread(new ThreadStart(server.Run)); + serverThread.Start(); + + Exception caught = null; + try + { + clientProtocol.Connect(clientImpl); + + // NOTE: Because we write-all before we read-any, this length can't be more than the pipe capacity + int length = 1000; + + byte[] data = new byte[length]; + secureRandom.NextBytes(data); + + Stream output = clientProtocol.Stream; + output.Write(data, 0, data.Length); + + byte[] echo = new byte[data.Length]; + int count = Streams.ReadFully(clientProtocol.Stream, echo); + + Assert.AreEqual(count, data.Length); + Assert.IsTrue(Arrays.AreEqual(data, echo)); + + output.Close(); + } + catch (Exception e) + { + caught = e; + LogException(caught); + } + + server.AllowExit(); + serverThread.Join(); + + Assert.IsTrue(clientNet.IsClosed, "Client Stream not closed"); + Assert.IsTrue(serverNet.IsClosed, "Server Stream not closed"); + + Assert.AreEqual(config.expectFatalAlertConnectionEnd, clientImpl.FirstFatalAlertConnectionEnd, "Client fatal alert connection end"); + Assert.AreEqual(config.expectFatalAlertConnectionEnd, serverImpl.FirstFatalAlertConnectionEnd, "Server fatal alert connection end"); + + Assert.AreEqual(config.expectFatalAlertDescription, clientImpl.FirstFatalAlertDescription, "Client fatal alert description"); + Assert.AreEqual(config.expectFatalAlertDescription, serverImpl.FirstFatalAlertDescription, "Server fatal alert description"); + + if (config.expectFatalAlertConnectionEnd == -1) + { + Assert.IsNull(caught, "Unexpected client exception"); + Assert.IsNull(server.mCaught, "Unexpected server exception"); + } + } + + protected virtual void LogException(Exception e) + { + if (TlsTestConfig.DEBUG) + { + Console.Error.WriteLine(e); + } + } + + internal class Server + { + protected readonly TlsTestCase mOuter; + protected readonly TlsServerProtocol mServerProtocol; + protected readonly TlsTestServerImpl mServerImpl; + + internal bool mCanExit = false; + internal Exception mCaught = null; + + internal Server(TlsTestCase outer, TlsServerProtocol serverProtocol, TlsTestServerImpl serverImpl) + { + this.mOuter = outer; + this.mServerProtocol = serverProtocol; + this.mServerImpl = serverImpl; + } + + internal void AllowExit() + { + lock (this) + { + mCanExit = true; + Monitor.PulseAll(this); + } + } + + public void Run() + { + try + { + mServerProtocol.Accept(mServerImpl); + Streams.PipeAll(mServerProtocol.Stream, mServerProtocol.Stream); + mServerProtocol.Close(); + } + catch (Exception e) + { + mCaught = e; + mOuter.LogException(mCaught); + } + + WaitExit(); + } + + protected void WaitExit() + { + lock (this) + { + while (!mCanExit) + { + try + { + Monitor.Wait(this); + } + catch (ThreadInterruptedException) + { + } + } + } + } + } + } +} diff --git a/crypto/test/src/crypto/tls/test/TlsTestClientImpl.cs b/crypto/test/src/crypto/tls/test/TlsTestClientImpl.cs new file mode 100644 index 000000000..48af9e0f8 --- /dev/null +++ b/crypto/test/src/crypto/tls/test/TlsTestClientImpl.cs @@ -0,0 +1,262 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + internal class TlsTestClientImpl + : DefaultTlsClient + { + protected readonly TlsTestConfig mConfig; + + protected int firstFatalAlertConnectionEnd = -1; + protected int firstFatalAlertDescription = -1; + + internal TlsTestClientImpl(TlsTestConfig config) + { + this.mConfig = config; + } + + internal int FirstFatalAlertConnectionEnd + { + get { return firstFatalAlertConnectionEnd; } + } + + internal int FirstFatalAlertDescription + { + get { return firstFatalAlertDescription; } + } + + public override ProtocolVersion ClientVersion + { + get + { + if (mConfig.clientOfferVersion != null) + { + return mConfig.clientOfferVersion; + } + + return base.ClientVersion; + } + } + + public override ProtocolVersion MinimumVersion + { + get + { + if (mConfig.clientMinimumVersion != null) + { + return mConfig.clientMinimumVersion; + } + + return base.MinimumVersion; + } + } + + public override bool IsFallback + { + get { return mConfig.clientFallback; } + } + + public override void NotifyAlertRaised(byte alertLevel, byte alertDescription, string message, Exception cause) + { + if (alertLevel == AlertLevel.fatal && firstFatalAlertConnectionEnd == -1) + { + firstFatalAlertConnectionEnd = ConnectionEnd.client; + firstFatalAlertDescription = alertDescription; + } + + if (TlsTestConfig.DEBUG) + { + TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; + output.WriteLine("TLS client raised alert: " + AlertLevel.GetText(alertLevel) + + ", " + AlertDescription.GetText(alertDescription)); + if (message != null) + { + output.WriteLine("> " + message); + } + if (cause != null) + { + output.WriteLine(cause); + } + } + } + + public override void NotifyAlertReceived(byte alertLevel, byte alertDescription) + { + if (alertLevel == AlertLevel.fatal && firstFatalAlertConnectionEnd == -1) + { + firstFatalAlertConnectionEnd = ConnectionEnd.server; + firstFatalAlertDescription = alertDescription; + } + + if (TlsTestConfig.DEBUG) + { + TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; + output.WriteLine("TLS client received alert: " + AlertLevel.GetText(alertLevel) + + ", " + AlertDescription.GetText(alertDescription)); + } + } + + public override void NotifyServerVersion(ProtocolVersion serverVersion) + { + base.NotifyServerVersion(serverVersion); + + if (TlsTestConfig.DEBUG) + { + Console.WriteLine("TLS client negotiated " + serverVersion); + } + } + + public override TlsAuthentication GetAuthentication() + { + return new MyTlsAuthentication(this, mContext); + } + + protected virtual Certificate CorruptCertificate(Certificate cert) + { + X509CertificateStructure[] certList = cert.GetCertificateList(); + certList[0] = CorruptCertificateSignature(certList[0]); + return new Certificate(certList); + } + + protected virtual X509CertificateStructure CorruptCertificateSignature(X509CertificateStructure cert) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.Add(cert.TbsCertificate); + v.Add(cert.SignatureAlgorithm); + v.Add(CorruptBitString(cert.Signature)); + + return X509CertificateStructure.GetInstance(new DerSequence(v)); + } + + protected virtual DerBitString CorruptBitString(DerBitString bs) + { + return new DerBitString(CorruptBit(bs.GetBytes())); + } + + protected virtual byte[] CorruptBit(byte[] bs) + { + bs = Arrays.Clone(bs); + + // Flip a random bit + int bit = mContext.SecureRandom.Next(bs.Length << 3); + bs[bit >> 3] ^= (byte)(1 << (bit & 7)); + + return bs; + } + + internal class MyTlsAuthentication + : TlsAuthentication + { + private readonly TlsTestClientImpl mOuter; + private readonly TlsContext mContext; + + internal MyTlsAuthentication(TlsTestClientImpl outer, TlsContext context) + { + this.mOuter = outer; + this.mContext = context; + } + + public virtual void NotifyServerCertificate(Certificate serverCertificate) + { + bool isEmpty = serverCertificate == null || serverCertificate.IsEmpty; + + X509CertificateStructure[] chain = serverCertificate.GetCertificateList(); + + // TODO Cache test resources? + if (isEmpty || !(chain[0].Equals(TlsTestUtilities.LoadCertificateResource("x509-server.pem")) + || chain[0].Equals(TlsTestUtilities.LoadCertificateResource("x509-server-dsa.pem")) + || chain[0].Equals(TlsTestUtilities.LoadCertificateResource("x509-server-ecdsa.pem")))) + { + throw new TlsFatalAlert(AlertDescription.bad_certificate); + } + + if (TlsTestConfig.DEBUG) + { + Console.WriteLine("TLS client received server certificate chain of length " + chain.Length); + for (int i = 0; i != chain.Length; i++) + { + X509CertificateStructure entry = chain[i]; + // TODO Create fingerprint based on certificate signature algorithm digest + Console.WriteLine(" fingerprint:SHA-256 " + TlsTestUtilities.Fingerprint(entry) + " (" + + entry.Subject + ")"); + } + } + } + + public virtual TlsCredentials GetClientCredentials(CertificateRequest certificateRequest) + { + if (mOuter.mConfig.serverCertReq == TlsTestConfig.SERVER_CERT_REQ_NONE) + throw new InvalidOperationException(); + if (mOuter.mConfig.clientAuth == TlsTestConfig.CLIENT_AUTH_NONE) + return null; + + byte[] certificateTypes = certificateRequest.CertificateTypes; + if (certificateTypes == null || !Arrays.Contains(certificateTypes, ClientCertificateType.rsa_sign)) + { + return null; + } + + TlsSignerCredentials signerCredentials = TlsTestUtilities.LoadSignerCredentials(mContext, + certificateRequest.SupportedSignatureAlgorithms, SignatureAlgorithm.rsa, + "x509-client.pem", "x509-client-key.pem"); + + if (mOuter.mConfig.clientAuth == TlsTestConfig.CLIENT_AUTH_VALID) + { + return signerCredentials; + } + + return new MyTlsSignerCredentials(mOuter, signerCredentials); + } + }; + + internal class MyTlsSignerCredentials + : TlsSignerCredentials + { + private readonly TlsTestClientImpl mOuter; + private readonly TlsSignerCredentials mInner; + + internal MyTlsSignerCredentials(TlsTestClientImpl outer, TlsSignerCredentials inner) + { + this.mOuter = outer; + this.mInner = inner; + } + + public virtual byte[] GenerateCertificateSignature(byte[] hash) + { + byte[] sig = mInner.GenerateCertificateSignature(hash); + + if (mOuter.mConfig.clientAuth == TlsTestConfig.CLIENT_AUTH_INVALID_VERIFY) + { + sig = mOuter.CorruptBit(sig); + } + + return sig; + } + + public virtual Certificate Certificate + { + get + { + Certificate cert = mInner.Certificate; + + if (mOuter.mConfig.clientAuth == TlsTestConfig.CLIENT_AUTH_INVALID_CERT) + { + cert = mOuter.CorruptCertificate(cert); + } + + return cert; + } + } + + public virtual SignatureAndHashAlgorithm SignatureAndHashAlgorithm + { + get { return mInner.SignatureAndHashAlgorithm; } + } + } + } +} diff --git a/crypto/test/src/crypto/tls/test/TlsTestConfig.cs b/crypto/test/src/crypto/tls/test/TlsTestConfig.cs new file mode 100644 index 000000000..0d1e7badb --- /dev/null +++ b/crypto/test/src/crypto/tls/test/TlsTestConfig.cs @@ -0,0 +1,101 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + public class TlsTestConfig + { + public static readonly bool DEBUG = false; + + /** + * Client does not authenticate, ignores any certificate request + */ + public const int CLIENT_AUTH_NONE = 0; + + /** + * Client will authenticate if it receives a certificate request + */ + public const int CLIENT_AUTH_VALID = 1; + + /** + * Client will authenticate if it receives a certificate request, with an invalid certificate + */ + public const int CLIENT_AUTH_INVALID_CERT = 2; + + /** + * Client will authenticate if it receives a certificate request, with an invalid CertificateVerify signature + */ + public const int CLIENT_AUTH_INVALID_VERIFY = 3; + + /** + * Server will not request a client certificate + */ + public const int SERVER_CERT_REQ_NONE = 0; + + /** + * Server will request a client certificate but receiving one is optional + */ + public const int SERVER_CERT_REQ_OPTIONAL = 1; + + /** + * Server will request a client certificate and receiving one is mandatory + */ + public const int SERVER_CERT_REQ_MANDATORY = 2; + + /** + * Configures the client authentication behaviour of the test client. Use CLIENT_AUTH_* constants. + */ + public int clientAuth = CLIENT_AUTH_VALID; + + /** + * Configures the minimum protocol version the client will accept. If null, uses the library's default. + */ + public ProtocolVersion clientMinimumVersion = null; + + /** + * Configures the protocol version the client will offer. If null, uses the library's default. + */ + public ProtocolVersion clientOfferVersion = null; + + /** + * Configures whether the client will indicate version fallback via TLS_FALLBACK_SCSV. + */ + public bool clientFallback = false; + + /** + * Configures whether the test server will send a certificate request. + */ + public int serverCertReq = SERVER_CERT_REQ_OPTIONAL; + + /** + * Configures the maximum protocol version the server will accept. If null, uses the library's default. + */ + public ProtocolVersion serverMaximumVersion = null; + + /** + * Configures the minimum protocol version the server will accept. If null, uses the library's default. + */ + public ProtocolVersion serverMinimumVersion = null; + + /** + * Configures the connection end that a fatal alert is expected to be raised. Use ConnectionEnd.* constants. + */ + public int expectFatalAlertConnectionEnd = -1; + + /** + * Configures the type of fatal alert expected to be raised. Use AlertDescription.* constants. + */ + public int expectFatalAlertDescription = -1; + + public void ExpectClientFatalAlert(byte alertDescription) + { + this.expectFatalAlertConnectionEnd = ConnectionEnd.client; + this.expectFatalAlertDescription = alertDescription; + } + + public void ExpectServerFatalAlert(byte alertDescription) + { + this.expectFatalAlertConnectionEnd = ConnectionEnd.server; + this.expectFatalAlertDescription = alertDescription; + } + } +} diff --git a/crypto/test/src/crypto/tls/test/TlsTestServerImpl.cs b/crypto/test/src/crypto/tls/test/TlsTestServerImpl.cs new file mode 100644 index 000000000..152d5dbdc --- /dev/null +++ b/crypto/test/src/crypto/tls/test/TlsTestServerImpl.cs @@ -0,0 +1,194 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + internal class TlsTestServerImpl + : DefaultTlsServer + { + protected readonly TlsTestConfig mConfig; + + protected int firstFatalAlertConnectionEnd = -1; + protected int firstFatalAlertDescription = -1; + + internal TlsTestServerImpl(TlsTestConfig config) + { + this.mConfig = config; + } + + internal int FirstFatalAlertConnectionEnd + { + get { return firstFatalAlertConnectionEnd; } + } + + internal int FirstFatalAlertDescription + { + get { return firstFatalAlertDescription; } + } + + protected override ProtocolVersion MaximumVersion + { + get + { + if (mConfig.serverMaximumVersion != null) + { + return mConfig.serverMaximumVersion; + } + + return base.MaximumVersion; + } + } + + protected override ProtocolVersion MinimumVersion + { + get + { + if (mConfig.serverMinimumVersion != null) + { + return mConfig.serverMinimumVersion; + } + + return base.MinimumVersion; + } + } + + public override void NotifyAlertRaised(byte alertLevel, byte alertDescription, string message, Exception cause) + { + if (alertLevel == AlertLevel.fatal && firstFatalAlertConnectionEnd == -1) + { + firstFatalAlertConnectionEnd = ConnectionEnd.server; + firstFatalAlertDescription = alertDescription; + } + + if (TlsTestConfig.DEBUG) + { + TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; + output.WriteLine("TLS server raised alert: " + AlertLevel.GetText(alertLevel) + + ", " + AlertDescription.GetText(alertDescription)); + if (message != null) + { + output.WriteLine("> " + message); + } + if (cause != null) + { + output.WriteLine(cause); + } + } + } + + public override void NotifyAlertReceived(byte alertLevel, byte alertDescription) + { + if (alertLevel == AlertLevel.fatal && firstFatalAlertConnectionEnd == -1) + { + firstFatalAlertConnectionEnd = ConnectionEnd.client; + firstFatalAlertDescription = alertDescription; + } + + if (TlsTestConfig.DEBUG) + { + TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; + output.WriteLine("TLS server received alert: " + AlertLevel.GetText(alertLevel) + + ", " + AlertDescription.GetText(alertDescription)); + } + } + + public override ProtocolVersion GetServerVersion() + { + ProtocolVersion serverVersion = base.GetServerVersion(); + + if (TlsTestConfig.DEBUG) + { + Console.WriteLine("TLS server negotiated " + serverVersion); + } + + return serverVersion; + } + + public override CertificateRequest GetCertificateRequest() + { + if (mConfig.serverCertReq == TlsTestConfig.SERVER_CERT_REQ_NONE) + { + return null; + } + + byte[] certificateTypes = new byte[]{ ClientCertificateType.rsa_sign, + ClientCertificateType.dss_sign, ClientCertificateType.ecdsa_sign }; + + IList serverSigAlgs = null; + if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(mServerVersion)) + { + serverSigAlgs = TlsUtilities.GetDefaultSupportedSignatureAlgorithms(); + } + + IList certificateAuthorities = new ArrayList(); + certificateAuthorities.Add(TlsTestUtilities.LoadCertificateResource("x509-ca.pem").Subject); + + return new CertificateRequest(certificateTypes, serverSigAlgs, certificateAuthorities); + } + + public override void NotifyClientCertificate(Certificate clientCertificate) + { + bool isEmpty = (clientCertificate == null || clientCertificate.IsEmpty); + + if (isEmpty != (mConfig.clientAuth == TlsTestConfig.CLIENT_AUTH_NONE)) + { + throw new InvalidOperationException(); + } + if (isEmpty && (mConfig.serverCertReq == TlsTestConfig.SERVER_CERT_REQ_MANDATORY)) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + X509CertificateStructure[] chain = clientCertificate.GetCertificateList(); + + // TODO Cache test resources? + if (!isEmpty && !(chain[0].Equals(TlsTestUtilities.LoadCertificateResource("x509-client.pem")) + || chain[0].Equals(TlsTestUtilities.LoadCertificateResource("x509-client-dsa.pem")) + || chain[0].Equals(TlsTestUtilities.LoadCertificateResource("x509-client-ecdsa.pem")))) + { + throw new TlsFatalAlert(AlertDescription.bad_certificate); + } + + if (TlsTestConfig.DEBUG) + { + Console.WriteLine("TLS server received client certificate chain of length " + chain.Length); + for (int i = 0; i != chain.Length; i++) + { + X509CertificateStructure entry = chain[i]; + // TODO Create fingerprint based on certificate signature algorithm digest + Console.WriteLine(" fingerprint:SHA-256 " + TlsTestUtilities.Fingerprint(entry) + " (" + + entry.Subject + ")"); + } + } + } + + protected override TlsSignerCredentials GetDsaSignerCredentials() + { + return TlsTestUtilities.LoadSignerCredentials(mContext, mSupportedSignatureAlgorithms, SignatureAlgorithm.dsa, + "x509-server-dsa.pem", "x509-server-key-dsa.pem"); + } + + protected override TlsSignerCredentials GetECDsaSignerCredentials() + { + return TlsTestUtilities.LoadSignerCredentials(mContext, mSupportedSignatureAlgorithms, SignatureAlgorithm.ecdsa, + "x509-server-ecdsa.pem", "x509-server-key-ecdsa.pem"); + } + + protected override TlsEncryptionCredentials GetRsaEncryptionCredentials() + { + return TlsTestUtilities.LoadEncryptionCredentials(mContext, new string[]{ "x509-server.pem", "x509-ca.pem" }, + "x509-server-key.pem"); + } + + protected override TlsSignerCredentials GetRsaSignerCredentials() + { + return TlsTestUtilities.LoadSignerCredentials(mContext, mSupportedSignatureAlgorithms, SignatureAlgorithm.rsa, + "x509-server.pem", "x509-server-key.pem"); + } + } +} diff --git a/crypto/test/src/crypto/tls/test/TlsTestSuite.cs b/crypto/test/src/crypto/tls/test/TlsTestSuite.cs new file mode 100644 index 000000000..dfd09d06e --- /dev/null +++ b/crypto/test/src/crypto/tls/test/TlsTestSuite.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections; + +using NUnit.Framework; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + public class TlsTestSuite + { + // Make the access to constants less verbose + internal class C : TlsTestConfig {} + + public TlsTestSuite() + { + } + + public static IEnumerable Suite() + { + IList testSuite = new ArrayList(); + + AddFallbackTests(testSuite); + AddVersionTests(testSuite, ProtocolVersion.TLSv10); + AddVersionTests(testSuite, ProtocolVersion.TLSv11); + AddVersionTests(testSuite, ProtocolVersion.TLSv12); + + return testSuite; + } + + private static void AddFallbackTests(IList testSuite) + { + { + TlsTestConfig c = CreateTlsTestConfig(ProtocolVersion.TLSv12); + c.clientFallback = true; + + testSuite.Add(new TestCaseData(c).SetName("FallbackGood")); + } + + { + TlsTestConfig c = CreateTlsTestConfig(ProtocolVersion.TLSv12); + c.clientOfferVersion = ProtocolVersion.TLSv11; + c.clientFallback = true; + c.ExpectServerFatalAlert(AlertDescription.inappropriate_fallback); + + testSuite.Add(new TestCaseData(c).SetName("FallbackBad")); + } + + { + TlsTestConfig c = CreateTlsTestConfig(ProtocolVersion.TLSv12); + c.clientOfferVersion = ProtocolVersion.TLSv11; + + testSuite.Add(new TestCaseData(c).SetName("FallbackNone")); + } + } + + private static void AddVersionTests(IList testSuite, ProtocolVersion version) + { + string prefix = version.ToString() + .Replace(" ", "") + .Replace("\\", "") + .Replace(".", "") + + "_"; + + { + TlsTestConfig c = CreateTlsTestConfig(version); + + testSuite.Add(new TestCaseData(c).SetName(prefix + "GoodDefault")); + } + + { + TlsTestConfig c = CreateTlsTestConfig(version); + c.clientAuth = C.CLIENT_AUTH_INVALID_VERIFY; + c.ExpectServerFatalAlert(AlertDescription.decrypt_error); + + testSuite.Add(new TestCaseData(c).SetName(prefix + "BadCertificateVerify")); + } + + { + TlsTestConfig c = CreateTlsTestConfig(version); + c.clientAuth = C.CLIENT_AUTH_INVALID_CERT; + c.ExpectServerFatalAlert(AlertDescription.bad_certificate); + + testSuite.Add(new TestCaseData(c).SetName(prefix + "BadClientCertificate")); + } + + { + TlsTestConfig c = CreateTlsTestConfig(version); + c.clientAuth = C.CLIENT_AUTH_NONE; + c.serverCertReq = C.SERVER_CERT_REQ_MANDATORY; + c.ExpectServerFatalAlert(AlertDescription.handshake_failure); + + testSuite.Add(new TestCaseData(c).SetName(prefix + "BadMandatoryCertReqDeclined")); + } + + { + TlsTestConfig c = CreateTlsTestConfig(version); + c.serverCertReq = C.SERVER_CERT_REQ_NONE; + + testSuite.Add(new TestCaseData(c).SetName(prefix + "GoodNoCertReq")); + } + + { + TlsTestConfig c = CreateTlsTestConfig(version); + c.clientAuth = C.CLIENT_AUTH_NONE; + + testSuite.Add(new TestCaseData(c).SetName(prefix + "GoodOptionalCertReqDeclined")); + } + } + + private static TlsTestConfig CreateTlsTestConfig(ProtocolVersion version) + { + TlsTestConfig c = new TlsTestConfig(); + c.clientMinimumVersion = ProtocolVersion.TLSv10; + c.clientOfferVersion = ProtocolVersion.TLSv12; + c.serverMaximumVersion = version; + c.serverMinimumVersion = ProtocolVersion.TLSv10; + return c; + } + } +} diff --git a/crypto/test/src/crypto/tls/test/TlsTestUtilities.cs b/crypto/test/src/crypto/tls/test/TlsTestUtilities.cs index 272dfd4fd..a76858ce6 100644 --- a/crypto/test/src/crypto/tls/test/TlsTestUtilities.cs +++ b/crypto/test/src/crypto/tls/test/TlsTestUtilities.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Globalization; using System.IO; using System.Text; @@ -89,6 +90,34 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests return new DefaultTlsSignerCredentials(context, certificate, privateKey, signatureAndHashAlgorithm); } + internal static TlsSignerCredentials LoadSignerCredentials(TlsContext context, IList supportedSignatureAlgorithms, + byte signatureAlgorithm, string certResource, string keyResource) + { + /* + * TODO Note that this code fails to provide default value for the client supported + * algorithms if it wasn't sent. + */ + + SignatureAndHashAlgorithm signatureAndHashAlgorithm = null; + if (supportedSignatureAlgorithms != null) + { + foreach (SignatureAndHashAlgorithm alg in supportedSignatureAlgorithms) + { + if (alg.Signature == signatureAlgorithm) + { + signatureAndHashAlgorithm = alg; + break; + } + } + + if (signatureAndHashAlgorithm == null) + return null; + } + + return LoadSignerCredentials(context, new String[]{ certResource, "x509-ca.pem" }, + keyResource, signatureAndHashAlgorithm); + } + internal static Certificate LoadCertificateChain(string[] resources) { X509CertificateStructure[] chain = new X509CertificateStructure[resources.Length]; diff --git a/crypto/test/src/crypto/tls/test/UnreliableDatagramTransport.cs b/crypto/test/src/crypto/tls/test/UnreliableDatagramTransport.cs new file mode 100644 index 000000000..b771ab7cf --- /dev/null +++ b/crypto/test/src/crypto/tls/test/UnreliableDatagramTransport.cs @@ -0,0 +1,84 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + public class UnreliableDatagramTransport + : DatagramTransport + { + private readonly DatagramTransport transport; + private readonly Random random; + private readonly int percentPacketLossReceiving, percentPacketLossSending; + + public UnreliableDatagramTransport(DatagramTransport transport, Random random, + int percentPacketLossReceiving, int percentPacketLossSending) + { + if (percentPacketLossReceiving < 0 || percentPacketLossReceiving > 100) + throw new ArgumentException("out of range", "percentPacketLossReceiving"); + if (percentPacketLossSending < 0 || percentPacketLossSending > 100) + throw new ArgumentException("out of range", "percentPacketLossSending"); + + this.transport = transport; + this.random = random; + this.percentPacketLossReceiving = percentPacketLossReceiving; + this.percentPacketLossSending = percentPacketLossSending; + } + + public virtual int GetReceiveLimit() + { + return transport.GetReceiveLimit(); + } + + public virtual int GetSendLimit() + { + return transport.GetSendLimit(); + } + + public virtual int Receive(byte[] buf, int off, int len, int waitMillis) + { + long endMillis = DateTimeUtilities.CurrentUnixMs() + waitMillis; + for (;;) + { + int length = transport.Receive(buf, off, len, waitMillis); + if (length < 0 || !LostPacket(percentPacketLossReceiving)) + { + return length; + } + + Console.WriteLine("PACKET LOSS (" + length + " byte packet not received)"); + + long now = DateTimeUtilities.CurrentUnixMs(); + if (now >= endMillis) + { + return -1; + } + + waitMillis = (int)(endMillis - now); + } + } + + public virtual void Send(byte[] buf, int off, int len) + { + if (LostPacket(percentPacketLossSending)) + { + Console.WriteLine("PACKET LOSS (" + len + " byte packet not sent)"); + } + else + { + transport.Send(buf, off, len); + } + } + + public virtual void Close() + { + transport.Close(); + } + + private bool LostPacket(int percentPacketLoss) + { + return percentPacketLoss > 0 && random.Next(100) < percentPacketLoss; + } + } +} diff --git a/crypto/test/src/math/ec/test/AllTests.cs b/crypto/test/src/math/ec/test/AllTests.cs index d4c7dc768..3e014ffd2 100644 --- a/crypto/test/src/math/ec/test/AllTests.cs +++ b/crypto/test/src/math/ec/test/AllTests.cs @@ -7,22 +7,21 @@ namespace Org.BouncyCastle.Math.EC.Tests { public class AllTests { - public static void Main( - string[] args) + public static void Main(string[] args) { -// junit.textui.TestRunner.run(suite()); - EventListener el = new NullListener(); - suite().Run(el); + Suite.Run(new NullListener(), NUnit.Core.TestFilter.Empty); } - public static TestSuite suite() + [Suite] + public static TestSuite Suite { - TestSuite suite = new TestSuite("EC Math tests"); - - suite.Add(new ECAlgorithmsTest()); - suite.Add(new ECPointTest()); - - return suite; + get + { + TestSuite suite = new TestSuite("EC Math tests"); + suite.Add(new ECAlgorithmsTest()); + suite.Add(new ECPointTest()); + return suite; + } } } } diff --git a/crypto/test/src/math/test/AllTests.cs b/crypto/test/src/math/test/AllTests.cs index 6f2b50140..40cfe3774 100644 --- a/crypto/test/src/math/test/AllTests.cs +++ b/crypto/test/src/math/test/AllTests.cs @@ -7,21 +7,20 @@ namespace Org.BouncyCastle.Math.Tests { public class AllTests { - public static void Main( - string[] args) + public static void Main(string[] args) { -// junit.textui.TestRunner.run(suite()); - EventListener el = new NullListener(); - suite().Run(el); + Suite.Run(new NullListener(), NUnit.Core.TestFilter.Empty); } - public static TestSuite suite() + [Suite] + public static TestSuite Suite { - TestSuite suite = new TestSuite("Math tests"); - - suite.Add(new BigIntegerTest()); - - return suite; + get + { + TestSuite suite = new TestSuite("Math tests"); + suite.Add(new BigIntegerTest()); + return suite; + } } } } diff --git a/crypto/test/src/ocsp/test/AllTests.cs b/crypto/test/src/ocsp/test/AllTests.cs index 2b30e3ad4..5e919fd91 100644 --- a/crypto/test/src/ocsp/test/AllTests.cs +++ b/crypto/test/src/ocsp/test/AllTests.cs @@ -9,21 +9,20 @@ namespace Org.BouncyCastle.Ocsp.Tests { public class AllTests { - public static void Main( - string[] args) - { - //junit.textui.TestRunner.run(suite()); - EventListener el = new NullListener(); - suite().Run(el); - } + public static void Main(string[] args) + { + Suite.Run(new NullListener(), NUnit.Core.TestFilter.Empty); + } - public static TestSuite suite() - { - TestSuite suite = new TestSuite("OCSP Tests"); - - suite.Add(new OcspTest()); - - return suite; - } + [Suite] + public static TestSuite Suite + { + get + { + TestSuite suite = new TestSuite("OCSP Tests"); + suite.Add(new OcspTest()); + return suite; + } + } } } diff --git a/crypto/test/src/openpgp/examples/test/AllTests.cs b/crypto/test/src/openpgp/examples/test/AllTests.cs index 180d2fa80..e9a7a744d 100644 --- a/crypto/test/src/openpgp/examples/test/AllTests.cs +++ b/crypto/test/src/openpgp/examples/test/AllTests.cs @@ -382,22 +382,20 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples.Tests return bRd.ReadLine(); } - public static void Main( - string[] args) - { - //junit.textui.TestRunner.run(suite()); - EventListener el = new NullListener(); - suite().Run(el); - } - - public static TestSuite suite() - { - TestSuite suite = new TestSuite("OpenPGP Example Tests"); - - suite.Add(new AllTests()); - - return suite; - } - + public static void Main(string[] args) + { + Suite.Run(new NullListener(), NUnit.Core.TestFilter.Empty); + } + + [Suite] + public static TestSuite Suite + { + get + { + TestSuite suite = new TestSuite("OpenPGP Example Tests"); + suite.Add(new AllTests()); + return suite; + } + } } } diff --git a/crypto/test/src/openssl/test/AllTests.cs b/crypto/test/src/openssl/test/AllTests.cs index 921208179..f843d0479 100644 --- a/crypto/test/src/openssl/test/AllTests.cs +++ b/crypto/test/src/openssl/test/AllTests.cs @@ -32,19 +32,24 @@ namespace Org.BouncyCastle.OpenSsl.Tests return (char[]) password.Clone(); } } - - [Suite] - public static TestSuite Suite - { - get - { - TestSuite suite = new TestSuite("OpenSSL Tests"); - suite.Add(new AllTests()); - return suite; - } - } - [Test] + public static void Main(string[] args) + { + Suite.Run(new NullListener(), NUnit.Core.TestFilter.Empty); + } + + [Suite] + public static TestSuite Suite + { + get + { + TestSuite suite = new TestSuite("OpenSSL Tests"); + suite.Add(new AllTests()); + return suite; + } + } + + [Test] public void TestOpenSsl() { Org.BouncyCastle.Utilities.Test.ITest[] tests = new Org.BouncyCastle.Utilities.Test.ITest[]{ @@ -121,13 +126,5 @@ namespace Org.BouncyCastle.OpenSsl.Tests Assert.AreEqual(privKey, rdKey); } - - public static void Main( - string[] args) - { - //junit.textui.TestRunner.run(suite()); - EventListener el = new NullListener(); - Suite.Run(el); - } } } diff --git a/crypto/test/src/tsp/test/AllTests.cs b/crypto/test/src/tsp/test/AllTests.cs index 66dc9c480..3e8b0cd5e 100644 --- a/crypto/test/src/tsp/test/AllTests.cs +++ b/crypto/test/src/tsp/test/AllTests.cs @@ -9,24 +9,23 @@ namespace Org.BouncyCastle.Tsp.Tests { public class AllTests { - public static void Main( - string[] args) + public static void Main(string[] args) { - //junit.textui.TestRunner.run(suite()); - EventListener el = new NullListener(); - suite().Run(el); + Suite.Run(new NullListener(), NUnit.Core.TestFilter.Empty); } - public static TestSuite suite() + [Suite] + public static TestSuite Suite { - TestSuite suite = new TestSuite("TSP Tests"); - - suite.Add(new GenTimeAccuracyUnitTest()); - suite.Add(new ParseTest()); - suite.Add(new TimeStampTokenInfoUnitTest()); - suite.Add(new TspTest()); - - return suite; + get + { + TestSuite suite = new TestSuite("TSP Tests"); + suite.Add(new GenTimeAccuracyUnitTest()); + suite.Add(new ParseTest()); + suite.Add(new TimeStampTokenInfoUnitTest()); + suite.Add(new TspTest()); + return suite; + } } } } diff --git a/crypto/test/src/util/io/pem/test/AllTests.cs b/crypto/test/src/util/io/pem/test/AllTests.cs index b44949383..c36f79304 100644 --- a/crypto/test/src/util/io/pem/test/AllTests.cs +++ b/crypto/test/src/util/io/pem/test/AllTests.cs @@ -19,18 +19,23 @@ namespace Org.BouncyCastle.Utilities.IO.Pem.Tests [TestFixture] public class AllTests { - [Suite] - public static TestSuite Suite - { - get - { - TestSuite suite = new TestSuite("PEM Utilities Tests"); - suite.Add(new AllTests()); - return suite; - } - } + public static void Main(string[] args) + { + Suite.Run(new NullListener(), NUnit.Core.TestFilter.Empty); + } - [Test] + [Suite] + public static TestSuite Suite + { + get + { + TestSuite suite = new TestSuite("PEM Utilities Tests"); + suite.Add(new AllTests()); + return suite; + } + } + + [Test] public void TestPemLength() { for (int i = 1; i != 60; i++) @@ -65,13 +70,5 @@ namespace Org.BouncyCastle.Utilities.IO.Pem.Tests Assert.AreEqual(sw.ToString().Length, pWrt.GetOutputSize(pemObj)); } - - public static void Main( - string[] args) - { - //junit.textui.TestRunner.run(suite()); - EventListener el = new NullListener(); - Suite.Run(el); - } } } |