diff options
author | Kenny Root <kroot@google.com> | 2014-07-11 17:15:21 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-07-10 20:49:23 +0000 |
commit | 86eae8dd1e7405394f0e9efe1252575ef9a9674c (patch) | |
tree | de008b1c273937dceaef9ebe6b3af043a6270c3e /luni | |
parent | a81c773918265370f73080af149d7252b320ad61 (diff) | |
parent | efc3147aae95283aa41e9aba10b54abac3cb90b1 (diff) | |
download | libcore-86eae8dd1e7405394f0e9efe1252575ef9a9674c.zip libcore-86eae8dd1e7405394f0e9efe1252575ef9a9674c.tar.gz libcore-86eae8dd1e7405394f0e9efe1252575ef9a9674c.tar.bz2 |
Merge "Invalidate cache of default SocketFactory"
Diffstat (limited to 'luni')
4 files changed, 193 insertions, 0 deletions
diff --git a/luni/src/main/java/java/security/Security.java b/luni/src/main/java/java/security/Security.java index 81bafbd..b859f9a 100644 --- a/luni/src/main/java/java/security/Security.java +++ b/luni/src/main/java/java/security/Security.java @@ -348,6 +348,7 @@ public final class Security { * Sets the value of the specified security property. */ public static void setProperty(String key, String value) { + Services.setNeedRefresh(); secprops.put(key, value); } diff --git a/luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java b/luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java index cce72cd..03b8828 100644 --- a/luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java +++ b/luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java @@ -20,6 +20,7 @@ package javax.net.ssl; import java.security.NoSuchAlgorithmException; import java.security.Security; import javax.net.ServerSocketFactory; +import org.apache.harmony.security.fortress.Services; /** * The factory for SSL server sockets. @@ -32,6 +33,8 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory { private static String defaultName; + private static int lastCacheVersion = -1; + /** * Returns the default {@code SSLServerSocketFactory} instance. The default * implementation is defined by the security property @@ -40,6 +43,12 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory { * @return the default {@code SSLServerSocketFactory} instance. */ public static synchronized ServerSocketFactory getDefault() { + int newCacheVersion = Services.getCacheVersion(); + if (lastCacheVersion != newCacheVersion) { + defaultServerSocketFactory = null; + defaultName = null; + lastCacheVersion = newCacheVersion; + } if (defaultServerSocketFactory != null) { return defaultServerSocketFactory; } diff --git a/luni/src/main/java/javax/net/ssl/SSLSocketFactory.java b/luni/src/main/java/javax/net/ssl/SSLSocketFactory.java index b07d0fd..5c0f15d 100644 --- a/luni/src/main/java/javax/net/ssl/SSLSocketFactory.java +++ b/luni/src/main/java/javax/net/ssl/SSLSocketFactory.java @@ -22,6 +22,7 @@ import java.net.Socket; import java.security.NoSuchAlgorithmException; import java.security.Security; import javax.net.SocketFactory; +import org.apache.harmony.security.fortress.Services; /** * The abstract factory implementation to create {@code SSLSocket}s. @@ -34,6 +35,8 @@ public abstract class SSLSocketFactory extends SocketFactory { private static String defaultName; + private static int lastCacheVersion = -1; + /** * Returns the default {@code SSLSocketFactory} instance. The default is * defined by the security property {@code 'ssl.SocketFactory.provider'}. @@ -41,6 +44,12 @@ public abstract class SSLSocketFactory extends SocketFactory { * @return the default ssl socket factory instance. */ public static synchronized SocketFactory getDefault() { + int newCacheVersion = Services.getCacheVersion(); + if (lastCacheVersion != newCacheVersion) { + defaultSocketFactory = null; + defaultName = null; + lastCacheVersion = newCacheVersion; + } if (defaultSocketFactory != null) { return defaultSocketFactory; } diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java index 86e96ff..d59bbb2 100644 --- a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java +++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java @@ -16,24 +16,198 @@ package libcore.javax.net.ssl; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; +import java.security.KeyManagementException; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.Security; +import java.util.Properties; import javax.net.ServerSocketFactory; import javax.net.SocketFactory; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLContextSpi; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLServerSocketFactory; +import javax.net.ssl.SSLSessionContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; import junit.framework.TestCase; +import libcore.java.security.StandardNames; public class SSLSocketFactoryTest extends TestCase { + private static final String SSL_PROPERTY = "ssl.SocketFactory.provider"; + public void test_SSLSocketFactory_getDefault() { SocketFactory sf = SSLSocketFactory.getDefault(); assertNotNull(sf); assertTrue(SSLSocketFactory.class.isAssignableFrom(sf.getClass())); } + public static class FakeSSLSocketProvider extends Provider { + public FakeSSLSocketProvider() { + super("FakeSSLSocketProvider", 1.0, "Testing provider"); + put("SSLContext.Default", FakeSSLContextSpi.class.getName()); + } + } + + public static final class FakeSSLContextSpi extends SSLContextSpi { + @Override + protected void engineInit(KeyManager[] keyManagers, TrustManager[] trustManagers, + SecureRandom secureRandom) throws KeyManagementException { + throw new UnsupportedOperationException(); + } + + @Override + protected SSLSocketFactory engineGetSocketFactory() { + return new FakeSSLSocketFactory(); + } + + @Override + protected SSLServerSocketFactory engineGetServerSocketFactory() { + throw new UnsupportedOperationException(); + } + + @Override + protected SSLEngine engineCreateSSLEngine(String s, int i) { + throw new UnsupportedOperationException(); + } + + @Override + protected SSLEngine engineCreateSSLEngine() { + throw new UnsupportedOperationException(); + } + + @Override + protected SSLSessionContext engineGetServerSessionContext() { + throw new UnsupportedOperationException(); + } + + @Override + protected SSLSessionContext engineGetClientSessionContext() { + throw new UnsupportedOperationException(); + } + } + + public static class FakeSSLSocketFactory extends SSLSocketFactory { + public FakeSSLSocketFactory() { + } + + @Override + public String[] getDefaultCipherSuites() { + throw new UnsupportedOperationException(); + } + + @Override + public String[] getSupportedCipherSuites() { + throw new UnsupportedOperationException(); + } + + @Override + public Socket createSocket(Socket s, String host, int port, boolean autoClose) { + throw new UnsupportedOperationException(); + } + + @Override + public Socket createSocket(InetAddress address, int port, InetAddress localAddress, + int localPort) { + throw new UnsupportedOperationException(); + } + + @Override + public Socket createSocket(InetAddress host, int port) { + throw new UnsupportedOperationException(); + } + + @Override + public Socket createSocket(String host, int port, InetAddress localHost, int localPort) { + throw new UnsupportedOperationException(); + } + + @Override + public Socket createSocket(String host, int port) { + throw new UnsupportedOperationException(); + } + } + + public void test_SSLSocketFactory_getDefault_cacheInvalidate() throws Exception { + String origProvider = resetSslProvider(); + try { + SocketFactory sf1 = SSLSocketFactory.getDefault(); + assertNotNull(sf1); + assertTrue(SSLSocketFactory.class.isAssignableFrom(sf1.getClass())); + + Provider fakeProvider = new FakeSSLSocketProvider(); + SocketFactory sf4 = null; + SSLContext origContext = null; + try { + origContext = SSLContext.getDefault(); + Security.insertProviderAt(fakeProvider, 1); + SSLContext.setDefault(SSLContext.getInstance("Default", fakeProvider)); + + sf4 = SSLSocketFactory.getDefault(); + assertNotNull(sf4); + assertTrue(SSLSocketFactory.class.isAssignableFrom(sf4.getClass())); + + assertFalse(sf1.getClass() + " should not be " + sf4.getClass(), + sf1.getClass().equals(sf4.getClass())); + } finally { + SSLContext.setDefault(origContext); + Security.removeProvider(fakeProvider.getName()); + } + + SocketFactory sf3 = SSLSocketFactory.getDefault(); + assertNotNull(sf3); + assertTrue(SSLSocketFactory.class.isAssignableFrom(sf3.getClass())); + + assertTrue(sf1.getClass() + " should be " + sf3.getClass(), + sf1.getClass().equals(sf3.getClass())); + + if (!StandardNames.IS_RI) { + Security.setProperty(SSL_PROPERTY, FakeSSLSocketFactory.class.getName()); + SocketFactory sf2 = SSLSocketFactory.getDefault(); + assertNotNull(sf2); + assertTrue(SSLSocketFactory.class.isAssignableFrom(sf2.getClass())); + + assertFalse(sf2.getClass().getName() + " should not be " + Security.getProperty(SSL_PROPERTY), + sf1.getClass().equals(sf2.getClass())); + assertTrue(sf2.getClass().equals(sf4.getClass())); + + resetSslProvider(); + } + } finally { + Security.setProperty(SSL_PROPERTY, origProvider); + } + } + + private String resetSslProvider() { + String origProvider = Security.getProperty(SSL_PROPERTY); + + try { + Field field_secprops = Security.class.getDeclaredField("secprops"); + field_secprops.setAccessible(true); + Properties secprops = (Properties) field_secprops.get(null); + secprops.remove(SSL_PROPERTY); + + Class<?> class_services = + Class.forName("org.apache.harmony.security.fortress.Services"); + Method m_setNeedRefresh = class_services.getMethod("setNeedRefresh"); + m_setNeedRefresh.invoke(null); + } catch (Exception e) { + e.printStackTrace(); + fail("Cannot find a way to clear out the SocketFactory provider"); + } + + return origProvider; + } + public void test_SSLSocketFactory_defaultConfiguration() throws Exception { SSLDefaultConfigurationAsserts.assertSSLSocketFactory( (SSLSocketFactory) SSLSocketFactory.getDefault()); |