Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2014-04-16 08:12:37 +0400
committerPeter Dettman <peter.dettman@bouncycastle.org>2014-04-16 08:12:37 +0400
commita55cbaeb973b4a51c2ba01269e4665494aa48951 (patch)
tree7fa430da8104a17a4d43ab7dd3ed840f94e9bd78 /core/src/test/java
parent1290f929d9157b7b2bd7edebb5576d6217500f70 (diff)
Add a DTLS test suite for client-auth use cases
Tests pass, but some disabled for automatic testing due to lack of clean exit
Diffstat (limited to 'core/src/test/java')
-rw-r--r--core/src/test/java/org/bouncycastle/crypto/tls/test/DTLSProtocolTest.java3
-rw-r--r--core/src/test/java/org/bouncycastle/crypto/tls/test/DTLSTestCase.java161
-rw-r--r--core/src/test/java/org/bouncycastle/crypto/tls/test/DTLSTestSuite.java92
-rw-r--r--core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestCase.java24
-rw-r--r--core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestClientImpl.java10
-rw-r--r--core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestConfig.java5
-rw-r--r--core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestSuite.java28
7 files changed, 309 insertions, 14 deletions
diff --git a/core/src/test/java/org/bouncycastle/crypto/tls/test/DTLSProtocolTest.java b/core/src/test/java/org/bouncycastle/crypto/tls/test/DTLSProtocolTest.java
index 441423b1..df5a3f87 100644
--- a/core/src/test/java/org/bouncycastle/crypto/tls/test/DTLSProtocolTest.java
+++ b/core/src/test/java/org/bouncycastle/crypto/tls/test/DTLSProtocolTest.java
@@ -44,9 +44,8 @@ public class DTLSProtocolTest
}
byte[] buf = new byte[dtlsClient.getReceiveLimit()];
- while (dtlsClient.receive(buf, 0, buf.length, 1000) >= 0)
+ while (dtlsClient.receive(buf, 0, buf.length, 100) >= 0)
{
- ;
}
dtlsClient.close();
diff --git a/core/src/test/java/org/bouncycastle/crypto/tls/test/DTLSTestCase.java b/core/src/test/java/org/bouncycastle/crypto/tls/test/DTLSTestCase.java
new file mode 100644
index 00000000..928647c1
--- /dev/null
+++ b/core/src/test/java/org/bouncycastle/crypto/tls/test/DTLSTestCase.java
@@ -0,0 +1,161 @@
+package org.bouncycastle.crypto.tls.test;
+
+import java.security.SecureRandom;
+
+import junit.framework.TestCase;
+
+import org.bouncycastle.crypto.tls.DTLSClientProtocol;
+import org.bouncycastle.crypto.tls.DTLSServerProtocol;
+import org.bouncycastle.crypto.tls.DTLSTransport;
+import org.bouncycastle.crypto.tls.DatagramTransport;
+import org.bouncycastle.crypto.tls.ProtocolVersion;
+import org.bouncycastle.util.Arrays;
+
+public class DTLSTestCase extends TestCase
+{
+ private static void checkDTLSVersion(ProtocolVersion version)
+ {
+ if (version != null && !version.isDTLS())
+ {
+ throw new IllegalStateException("Non-DTLS version");
+ }
+ }
+
+ protected final TlsTestConfig config;
+
+ public DTLSTestCase(TlsTestConfig config, String name)
+ {
+ checkDTLSVersion(config.clientMinimumVersion);
+ checkDTLSVersion(config.clientOfferVersion);
+ checkDTLSVersion(config.serverMaximumVersion);
+ checkDTLSVersion(config.serverMinimumVersion);
+
+ this.config = config;
+
+ setName(name);
+ }
+
+ protected void runTest() throws Throwable
+ {
+ 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);
+
+ ServerThread serverThread = new ServerThread(serverProtocol, network.getServer(), serverImpl);
+ serverThread.start();
+
+ Exception caught = null;
+ try
+ {
+ DatagramTransport clientTransport = network.getClient();
+
+ if (TlsTestConfig.DEBUG)
+ {
+ clientTransport = new LoggingDatagramTransport(clientTransport, System.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);
+ }
+
+ serverThread.shutdown();
+
+ // TODO Add checks that the various streams were closed
+
+ assertEquals("Client fatal alert connection end", config.expectFatalAlertConnectionEnd, clientImpl.firstFatalAlertConnectionEnd);
+ assertEquals("Server fatal alert connection end", config.expectFatalAlertConnectionEnd, serverImpl.firstFatalAlertConnectionEnd);
+
+ assertEquals("Client fatal alert description", config.expectFatalAlertDescription, clientImpl.firstFatalAlertDescription);
+ assertEquals("Server fatal alert description", config.expectFatalAlertDescription, serverImpl.firstFatalAlertDescription);
+
+ if (config.expectFatalAlertConnectionEnd == -1)
+ {
+ assertNull("Unexpected client exception", caught);
+ assertNull("Unexpected server exception", serverThread.caught);
+ }
+ }
+
+ protected void logException(Exception e)
+ {
+ if (TlsTestConfig.DEBUG)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ class ServerThread
+ extends Thread
+ {
+ private final DTLSServerProtocol serverProtocol;
+ private final DatagramTransport serverTransport;
+ private final TlsTestServerImpl serverImpl;
+
+ private volatile boolean isShutdown = false;
+ Exception caught = null;
+
+ ServerThread(DTLSServerProtocol serverProtocol, DatagramTransport serverTransport, TlsTestServerImpl serverImpl)
+ {
+ this.serverProtocol = serverProtocol;
+ this.serverTransport = serverTransport;
+ this.serverImpl = serverImpl;
+ }
+
+ public void run()
+ {
+ try
+ {
+ DTLSTransport dtlsServer = serverProtocol.accept(serverImpl, serverTransport);
+ 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)
+ {
+ caught = e;
+ logException(caught);
+ }
+ }
+
+ void shutdown()
+ throws InterruptedException
+ {
+ if (!isShutdown)
+ {
+ isShutdown = true;
+ this.interrupt();
+ this.join();
+ }
+ }
+ }
+}
diff --git a/core/src/test/java/org/bouncycastle/crypto/tls/test/DTLSTestSuite.java b/core/src/test/java/org/bouncycastle/crypto/tls/test/DTLSTestSuite.java
new file mode 100644
index 00000000..bd066f85
--- /dev/null
+++ b/core/src/test/java/org/bouncycastle/crypto/tls/test/DTLSTestSuite.java
@@ -0,0 +1,92 @@
+package org.bouncycastle.crypto.tls.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.bouncycastle.crypto.tls.ProtocolVersion;
+
+public class DTLSTestSuite extends TestSuite
+{
+ // Make the access to constants less verbose
+ static abstract class C extends TlsTestConfig {}
+
+ public static Test suite()
+ {
+ DTLSTestSuite testSuite = new DTLSTestSuite();
+
+ addVersionTests(testSuite, ProtocolVersion.DTLSv10);
+ addVersionTests(testSuite, ProtocolVersion.DTLSv12);
+
+ return testSuite;
+ }
+
+ private static void addVersionTests(TestSuite testSuite, ProtocolVersion version)
+ {
+ String prefix = version.toString().replaceAll("[ \\.]", "") + "_";
+
+ /*
+ * 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.addTest(new DTLSTestCase(c, prefix + "BadCertificateVerify"));
+// }
+//
+// {
+// TlsTestConfig c = createDTLSTestConfig(version);
+// c.clientAuth = C.CLIENT_AUTH_INVALID_CERT;
+// c.expectServerFatalAlert(AlertDescription.bad_certificate);
+//
+// testSuite.addTest(new DTLSTestCase(c, 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.addTest(new DTLSTestCase(c, prefix + "BadMandatoryCertReqDeclined"));
+// }
+
+ {
+ TlsTestConfig c = createDTLSTestConfig(version);
+
+ testSuite.addTest(new DTLSTestCase(c, prefix + "GoodDefault"));
+ }
+
+ {
+ TlsTestConfig c = createDTLSTestConfig(version);
+ c.serverCertReq = C.SERVER_CERT_REQ_NONE;
+
+ testSuite.addTest(new DTLSTestCase(c, prefix + "GoodNoCertReq"));
+ }
+
+ {
+ TlsTestConfig c = createDTLSTestConfig(version);
+ c.clientAuth = C.CLIENT_AUTH_NONE;
+
+ testSuite.addTest(new DTLSTestCase(c, 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/core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestCase.java b/core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestCase.java
index 9cdd8014..79ad7844 100644
--- a/core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestCase.java
+++ b/core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestCase.java
@@ -7,6 +7,7 @@ import java.security.SecureRandom;
import junit.framework.TestCase;
+import org.bouncycastle.crypto.tls.ProtocolVersion;
import org.bouncycastle.crypto.tls.TlsClientProtocol;
import org.bouncycastle.crypto.tls.TlsServerProtocol;
import org.bouncycastle.util.Arrays;
@@ -14,10 +15,23 @@ import org.bouncycastle.util.io.Streams;
public class TlsTestCase extends TestCase
{
+ private static void checkTLSVersion(ProtocolVersion version)
+ {
+ if (version != null && !version.isTLS())
+ {
+ throw new IllegalStateException("Non-TLS version");
+ }
+ }
+
protected final TlsTestConfig config;
public TlsTestCase(TlsTestConfig config, String name)
{
+ checkTLSVersion(config.clientMinimumVersion);
+ checkTLSVersion(config.clientOfferVersion);
+ checkTLSVersion(config.serverMaximumVersion);
+ checkTLSVersion(config.serverMinimumVersion);
+
this.config = config;
setName(name);
@@ -71,6 +85,7 @@ public class TlsTestCase extends TestCase
catch (Exception e)
{
caught = e;
+ logException(caught);
}
serverThread.allowExit();
@@ -94,6 +109,14 @@ public class TlsTestCase extends TestCase
}
}
+ protected void logException(Exception e)
+ {
+ if (TlsTestConfig.DEBUG)
+ {
+ e.printStackTrace();
+ }
+ }
+
class ServerThread extends Thread
{
protected final TlsServerProtocol serverProtocol;
@@ -125,6 +148,7 @@ public class TlsTestCase extends TestCase
catch (Exception e)
{
caught = e;
+ logException(caught);
}
waitExit();
diff --git a/core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestClientImpl.java b/core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestClientImpl.java
index 4f5be8e3..4bc76e68 100644
--- a/core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestClientImpl.java
+++ b/core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestClientImpl.java
@@ -56,6 +56,16 @@ class TlsTestClientImpl
return super.getClientVersion();
}
+ public ProtocolVersion getMinimumVersion()
+ {
+ if (config.clientMinimumVersion != null)
+ {
+ return config.clientMinimumVersion;
+ }
+
+ return super.getMinimumVersion();
+ }
+
public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause)
{
if (alertLevel == AlertLevel.fatal && firstFatalAlertConnectionEnd == -1)
diff --git a/core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestConfig.java b/core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestConfig.java
index 3784bc23..6110458e 100644
--- a/core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestConfig.java
+++ b/core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestConfig.java
@@ -48,6 +48,11 @@ public class TlsTestConfig
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;
diff --git a/core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestSuite.java b/core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestSuite.java
index 9028cbe4..eed9b071 100644
--- a/core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestSuite.java
+++ b/core/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestSuite.java
@@ -27,54 +27,58 @@ public class TlsTestSuite extends TestSuite
String prefix = version.toString().replaceAll("[ \\.]", "") + "_";
{
- TlsTestConfig c = new TlsTestConfig();
- c.serverMaximumVersion = version;
+ TlsTestConfig c = createTlsTestConfig(version);
testSuite.addTest(new TlsTestCase(c, prefix + "GoodDefault"));
}
{
- TlsTestConfig c = new TlsTestConfig();
+ TlsTestConfig c = createTlsTestConfig(version);
c.clientAuth = C.CLIENT_AUTH_INVALID_VERIFY;
- c.serverMaximumVersion = version;
c.expectServerFatalAlert(AlertDescription.decrypt_error);
testSuite.addTest(new TlsTestCase(c, prefix + "BadCertificateVerify"));
}
{
- TlsTestConfig c = new TlsTestConfig();
+ TlsTestConfig c = createTlsTestConfig(version);
c.clientAuth = C.CLIENT_AUTH_INVALID_CERT;
- c.serverMaximumVersion = version;
c.expectServerFatalAlert(AlertDescription.bad_certificate);
testSuite.addTest(new TlsTestCase(c, prefix + "BadClientCertificate"));
}
{
- TlsTestConfig c = new TlsTestConfig();
+ TlsTestConfig c = createTlsTestConfig(version);
c.clientAuth = C.CLIENT_AUTH_NONE;
c.serverCertReq = C.SERVER_CERT_REQ_MANDATORY;
- c.serverMaximumVersion = version;
c.expectServerFatalAlert(AlertDescription.handshake_failure);
testSuite.addTest(new TlsTestCase(c, prefix + "BadMandatoryCertReqDeclined"));
}
{
- TlsTestConfig c = new TlsTestConfig();
+ TlsTestConfig c = createTlsTestConfig(version);
c.serverCertReq = C.SERVER_CERT_REQ_NONE;
- c.serverMaximumVersion = version;
testSuite.addTest(new TlsTestCase(c, prefix + "GoodNoCertReq"));
}
{
- TlsTestConfig c = new TlsTestConfig();
+ TlsTestConfig c = createTlsTestConfig(version);
c.clientAuth = C.CLIENT_AUTH_NONE;
- c.serverMaximumVersion = version;
testSuite.addTest(new TlsTestCase(c, 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;
+ }
}