summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Hudson <nick.hudson@isode.com>2013-04-03 10:54:02 (GMT)
committerNick Hudson <nick.hudson@isode.com>2013-04-11 09:19:22 (GMT)
commitb50d3949d81d8cece6c71c2b094297317e584308 (patch)
tree81837d7a977700f590a2ccace53166564b70a4a6
parent00a381a2121fe68d318cddceed32d8bb230935ea (diff)
downloadstroke-b50d3949d81d8cece6c71c2b094297317e584308.zip
stroke-b50d3949d81d8cece6c71c2b094297317e584308.tar.bz2
Provide mechanism to allow clients to restrict available ciphersuites
By default, when a TLS connection is established, the SSLContext will enable all available ciphersuites. This may not be appropriate in situations where export restrictions apply and higher grade ciphersuites are prohibitied. This change allows a caller to configure a restricted set of ciphersuites to be used when establishing TLS connections. Callers use the JSSEContextFactory.setRestrictedCipherSuites() method to configure a list of ciphersuites. Any ciphersuites which are not included in the list will be excluded in subsequent TLS connections. If the JSSEContextFactory.setRestrictedCipherSuites() is never called, or called with a null parameter, then no restriction will apply. Test-information: Validated that by calling the new method to restrict the available ciphers, TLS connections initiated by Stroke only propose ciphersuites in the restricted list, and connections fail when the server fails to find an acceptable cipher. Change-Id: Id0b4b19553a6f386cda27a71f0172410d899218e Signed-off-by: Nick Hudson <nick.hudson@isode.com>
-rw-r--r--src/com/isode/stroke/tls/PlatformTLSFactories.java6
-rw-r--r--src/com/isode/stroke/tls/java/JSSEContext.java37
-rw-r--r--src/com/isode/stroke/tls/java/JSSEContextFactory.java35
3 files changed, 70 insertions, 8 deletions
diff --git a/src/com/isode/stroke/tls/PlatformTLSFactories.java b/src/com/isode/stroke/tls/PlatformTLSFactories.java
index 6b98a95..cbfcfe2 100644
--- a/src/com/isode/stroke/tls/PlatformTLSFactories.java
+++ b/src/com/isode/stroke/tls/PlatformTLSFactories.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Isode Limited, London, England.
+ * Copyright (c) 2012-2013 Isode Limited, London, England.
* All rights reserved.
*/
/*
@@ -11,8 +11,10 @@ package com.isode.stroke.tls;
import com.isode.stroke.tls.java.JSSEContextFactory;
public class PlatformTLSFactories {
+ private JSSEContextFactory contextFactory = new JSSEContextFactory();
+
public TLSContextFactory getTLSContextFactory() {
- return new JSSEContextFactory();
+ return contextFactory;
}
public CertificateFactory getCertificateFactory() {
diff --git a/src/com/isode/stroke/tls/java/JSSEContext.java b/src/com/isode/stroke/tls/java/JSSEContext.java
index 9cb0109..257a70c 100644
--- a/src/com/isode/stroke/tls/java/JSSEContext.java
+++ b/src/com/isode/stroke/tls/java/JSSEContext.java
@@ -26,6 +26,8 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
+import java.util.HashSet;
+import java.util.Set;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -117,13 +119,14 @@ public class JSSEContext extends TLSContext {
@Override
public void connect() {
try {
- doSetup();
+ doSetup();
}
catch (SSLException e) {
emitError(e,"doSetup() failed");
}
}
+
private void doSetup() throws SSLException {
SSLContext sslContext = getSSLContext();
@@ -143,6 +146,23 @@ public class JSSEContext extends TLSContext {
/* "the SSLContextImpl requires initialization and init() has not been called" */
throw new SSLException(e);
}
+
+ /* Restrict cipher suites if necessary */
+ if (restrictedCipherSuites != null) {
+ String[] supportedSuites = sslEngine.getSupportedCipherSuites();
+ Set<String> matchedSuites = new HashSet<String>();
+ for (String suite:supportedSuites) {
+ if (restrictedCipherSuites.contains(suite)) {
+ matchedSuites.add(suite);
+ }
+ }
+ String[] suitesToEnable = new String[]{};
+ if (!matchedSuites.isEmpty()) {
+ suitesToEnable = (String[])matchedSuites.toArray();
+ }
+
+ sslEngine.setEnabledCipherSuites(suitesToEnable);
+ }
sslEngine.setUseClientMode(true); /* I am a client */
sslEngine.setEnableSessionCreation(true); /* can create new sessions */
@@ -1018,10 +1038,21 @@ public class JSSEContext extends TLSContext {
/**
* Construct a new JSSEContext object.
+ * @param restrictedCipherSuites a list of cipher suites that are to be
+ * enabled for this context. Null means no restriction
*/
- public JSSEContext() {
- /* */
+ public JSSEContext(Set<String> restrictedCipherSuites) {
+ if (restrictedCipherSuites != null) {
+ this.restrictedCipherSuites = new HashSet<String>(restrictedCipherSuites);
+ }
}
+
+
+ /**
+ * Specific list of suites to allow - null (the default) means
+ * no restriction.
+ */
+ private Set<String> restrictedCipherSuites = null;
/**
* Reference to the SSLEngine being used
diff --git a/src/com/isode/stroke/tls/java/JSSEContextFactory.java b/src/com/isode/stroke/tls/java/JSSEContextFactory.java
index 0ddb4fd..63b184d 100644
--- a/src/com/isode/stroke/tls/java/JSSEContextFactory.java
+++ b/src/com/isode/stroke/tls/java/JSSEContextFactory.java
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Isode Limited, London, England.
+/* Copyright (c) 2012-2013, Isode Limited, London, England.
* All rights reserved.
*
* Acquisition and use of this software and related materials for any
@@ -10,12 +10,19 @@
package com.isode.stroke.tls.java;
+import java.util.HashSet;
+import java.util.Set;
+
import com.isode.stroke.tls.TLSContext;
import com.isode.stroke.tls.TLSContextFactory;
/**
* Concrete implementation of a TLSContextFactory which uses SSLEngine
- * and maybe other stuff? ..tbs...
+ *
+ * <p>Ciphersuite names recognised by this class correspond to the standard
+ * names as described in
+ * <a href=http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#ciphersuites>
+ * Oracle's "Java Cryptography Architecture Standard Algorithm Name Documentation"</a>.
*
*/
public class JSSEContextFactory implements TLSContextFactory {
@@ -27,7 +34,29 @@ public class JSSEContextFactory implements TLSContextFactory {
@Override
public TLSContext createTLSContext() {
- return new JSSEContext();
+ return new JSSEContext(restrictedCipherSuites);
}
+
+ private static Set<String> restrictedCipherSuites = null;
+
+ /**
+ * Restrict which cipher suites are to be enabled for any TLSContexts
+ * returned by this factory from now on. Any name which is
+ * not recognised, or not available is ignored: this method cannot be
+ * used to enable otherwise unavailable ciphersuites.
+ *
+ * @param cipherSuites a set of cipher suite names. If this parameter is
+ * null, then no restriction on cipher suites applies (all suites available
+ * to the implementation will be enabled).
+ *
+ */
+ public static void setRestrictedCipherSuites(Set<String> cipherSuites) {
+ if (cipherSuites == null) {
+ restrictedCipherSuites = null;
+ return;
+ }
+
+ restrictedCipherSuites = new HashSet<String>(cipherSuites);
+ }
}