1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package libcore.javax.net.ssl; 18 19import java.util.ArrayList; 20import java.util.Arrays; 21import java.util.Collections; 22import java.util.Enumeration; 23import java.util.Iterator; 24import java.util.LinkedList; 25import java.util.List; 26import javax.net.ssl.SSLSessionContext; 27import javax.net.ssl.SSLSocket; 28import junit.framework.TestCase; 29 30public class SSLSessionContextTest extends TestCase { 31 32 public static final void assertSSLSessionContextSize(int expected, TestSSLContext c) { 33 assertSSLSessionContextSize(expected, 34 c.clientContext.getClientSessionContext(), 35 c.serverContext.getServerSessionContext()); 36 assertSSLSessionContextSize(0, 37 c.serverContext.getClientSessionContext(), 38 c.clientContext.getServerSessionContext()); 39 } 40 41 public static final void assertSSLSessionContextSize(int expected, 42 SSLSessionContext client, 43 SSLSessionContext server) { 44 assertSSLSessionContextSize(expected, client, false); 45 assertSSLSessionContextSize(expected, server, true); 46 } 47 48 public static final void assertSSLSessionContextSize(int expected, 49 SSLSessionContext s, 50 boolean server) { 51 int size = Collections.list(s.getIds()).size(); 52 if (server && TestSSLContext.sslServerSocketSupportsSessionTickets()) { 53 assertEquals(0, size); 54 } else { 55 assertEquals(expected, size); 56 } 57 } 58 59 public void test_SSLSessionContext_getIds() { 60 TestSSLContext c = TestSSLContext.create(); 61 assertSSLSessionContextSize(0, c); 62 c.close(); 63 64 TestSSLSocketPair s = TestSSLSocketPair.create(); 65 assertSSLSessionContextSize(1, s.c); 66 Enumeration clientIds = s.c.clientContext.getClientSessionContext().getIds(); 67 Enumeration serverIds = s.c.serverContext.getServerSessionContext().getIds(); 68 byte[] clientId = (byte[]) clientIds.nextElement(); 69 assertEquals(32, clientId.length); 70 if (TestSSLContext.sslServerSocketSupportsSessionTickets()) { 71 assertFalse(serverIds.hasMoreElements()); 72 } else { 73 byte[] serverId = (byte[]) serverIds.nextElement(); 74 assertEquals(32, serverId.length); 75 assertTrue(Arrays.equals(clientId, serverId)); 76 } 77 s.close(); 78 } 79 80 public void test_SSLSessionContext_getSession() { 81 TestSSLContext c = TestSSLContext.create(); 82 try { 83 c.clientContext.getClientSessionContext().getSession(null); 84 fail(); 85 } catch (NullPointerException expected) { 86 } 87 assertNull(c.clientContext.getClientSessionContext().getSession(new byte[0])); 88 assertNull(c.clientContext.getClientSessionContext().getSession(new byte[1])); 89 try { 90 c.serverContext.getServerSessionContext().getSession(null); 91 fail(); 92 } catch (NullPointerException expected) { 93 } 94 assertNull(c.serverContext.getServerSessionContext().getSession(new byte[0])); 95 assertNull(c.serverContext.getServerSessionContext().getSession(new byte[1])); 96 c.close(); 97 98 TestSSLSocketPair s = TestSSLSocketPair.create(); 99 SSLSessionContext client = s.c.clientContext.getClientSessionContext(); 100 SSLSessionContext server = s.c.serverContext.getServerSessionContext(); 101 byte[] clientId = (byte[]) client.getIds().nextElement(); 102 assertNotNull(client.getSession(clientId)); 103 assertTrue(Arrays.equals(clientId, client.getSession(clientId).getId())); 104 if (TestSSLContext.sslServerSocketSupportsSessionTickets()) { 105 assertFalse(server.getIds().hasMoreElements()); 106 } else { 107 byte[] serverId = (byte[]) server.getIds().nextElement(); 108 assertNotNull(server.getSession(serverId)); 109 assertTrue(Arrays.equals(serverId, server.getSession(serverId).getId())); 110 } 111 s.close(); 112 } 113 114 public void test_SSLSessionContext_getSessionCacheSize() { 115 TestSSLContext c = TestSSLContext.create(); 116 assertEquals(TestSSLContext.EXPECTED_DEFAULT_CLIENT_SSL_SESSION_CACHE_SIZE, 117 c.clientContext.getClientSessionContext().getSessionCacheSize()); 118 assertEquals(TestSSLContext.EXPECTED_DEFAULT_SERVER_SSL_SESSION_CACHE_SIZE, 119 c.serverContext.getServerSessionContext().getSessionCacheSize()); 120 c.close(); 121 122 TestSSLSocketPair s = TestSSLSocketPair.create(); 123 assertEquals(TestSSLContext.EXPECTED_DEFAULT_CLIENT_SSL_SESSION_CACHE_SIZE, 124 s.c.clientContext.getClientSessionContext().getSessionCacheSize()); 125 assertEquals(TestSSLContext.EXPECTED_DEFAULT_SERVER_SSL_SESSION_CACHE_SIZE, 126 s.c.serverContext.getServerSessionContext().getSessionCacheSize()); 127 s.close(); 128 } 129 130 public void test_SSLSessionContext_setSessionCacheSize_noConnect() { 131 TestSSLContext c = TestSSLContext.create(); 132 assertNoConnectSetSessionCacheSizeBehavior( 133 TestSSLContext.EXPECTED_DEFAULT_CLIENT_SSL_SESSION_CACHE_SIZE, 134 c.clientContext.getClientSessionContext()); 135 assertNoConnectSetSessionCacheSizeBehavior( 136 TestSSLContext.EXPECTED_DEFAULT_SERVER_SSL_SESSION_CACHE_SIZE, 137 c.serverContext.getServerSessionContext()); 138 c.close(); 139 } 140 141 private static void assertNoConnectSetSessionCacheSizeBehavior(int expectedDefault, 142 SSLSessionContext s) { 143 try { 144 s.setSessionCacheSize(-1); 145 fail(); 146 } catch (IllegalArgumentException expected) { 147 } 148 assertEquals(expectedDefault, s.getSessionCacheSize()); 149 s.setSessionCacheSize(1); 150 assertEquals(1, s.getSessionCacheSize()); 151 } 152 153 public void test_SSLSessionContext_setSessionCacheSize_oneConnect() { 154 TestSSLSocketPair s = TestSSLSocketPair.create(); 155 SSLSessionContext client = s.c.clientContext.getClientSessionContext(); 156 SSLSessionContext server = s.c.serverContext.getServerSessionContext(); 157 assertEquals(TestSSLContext.EXPECTED_DEFAULT_CLIENT_SSL_SESSION_CACHE_SIZE, 158 client.getSessionCacheSize()); 159 assertEquals(TestSSLContext.EXPECTED_DEFAULT_SERVER_SSL_SESSION_CACHE_SIZE, 160 server.getSessionCacheSize()); 161 assertSSLSessionContextSize(1, s.c); 162 s.close(); 163 } 164 165 public void test_SSLSessionContext_setSessionCacheSize_dynamic() throws Exception { 166 TestSSLContext c = TestSSLContext.create(); 167 SSLSessionContext client = c.clientContext.getClientSessionContext(); 168 SSLSessionContext server = c.serverContext.getServerSessionContext(); 169 170 String[] supportedCipherSuites = c.serverSocket.getSupportedCipherSuites(); 171 c.serverSocket.setEnabledCipherSuites(supportedCipherSuites); 172 LinkedList<String> uniqueCipherSuites 173 = new LinkedList(Arrays.asList(supportedCipherSuites)); 174 // only use RSA cipher suites which will work with our TrustProvider 175 Iterator<String> i = uniqueCipherSuites.iterator(); 176 while (i.hasNext()) { 177 String cipherSuite = i.next(); 178 179 // Certificate key length too long for export ciphers 180 if (cipherSuite.startsWith("SSL_RSA_EXPORT_")) { 181 i.remove(); 182 continue; 183 } 184 185 if (cipherSuite.startsWith("SSL_RSA_")) { 186 continue; 187 } 188 if (cipherSuite.startsWith("TLS_RSA_")) { 189 continue; 190 } 191 if (cipherSuite.startsWith("TLS_DHE_RSA_")) { 192 continue; 193 } 194 if (cipherSuite.startsWith("SSL_DHE_RSA_")) { 195 continue; 196 } 197 i.remove(); 198 } 199 200 /* 201 * having more than 3 uniqueCipherSuites is a test 202 * requirement, not a requirement of the interface or 203 * implementation. It simply allows us to make sure that we 204 * will not get a cached session ID since we'll have to 205 * renegotiate a new session due to the new cipher suite 206 * requirement. even this test only really needs three if it 207 * reused the unique cipher suites every time it resets the 208 * session cache. 209 */ 210 assertTrue(uniqueCipherSuites.size() >= 3); 211 String cipherSuite1 = uniqueCipherSuites.get(0); 212 String cipherSuite2 = uniqueCipherSuites.get(1); 213 String cipherSuite3 = uniqueCipherSuites.get(2); 214 215 List<SSLSocket[]> toClose = new ArrayList<SSLSocket[]>(); 216 toClose.add(TestSSLSocketPair.connect(c, new String[] { cipherSuite1 }, null)); 217 assertSSLSessionContextSize(1, c); 218 toClose.add(TestSSLSocketPair.connect(c, new String[] { cipherSuite2 }, null)); 219 assertSSLSessionContextSize(2, c); 220 toClose.add(TestSSLSocketPair.connect(c, new String[] { cipherSuite3 }, null)); 221 assertSSLSessionContextSize(3, c); 222 223 client.setSessionCacheSize(1); 224 server.setSessionCacheSize(1); 225 assertEquals(1, client.getSessionCacheSize()); 226 assertEquals(1, server.getSessionCacheSize()); 227 assertSSLSessionContextSize(1, c); 228 toClose.add(TestSSLSocketPair.connect(c, new String[] { cipherSuite1 }, null)); 229 assertSSLSessionContextSize(1, c); 230 231 client.setSessionCacheSize(2); 232 server.setSessionCacheSize(2); 233 toClose.add(TestSSLSocketPair.connect(c, new String[] { cipherSuite2 }, null)); 234 assertSSLSessionContextSize(2, c); 235 toClose.add(TestSSLSocketPair.connect(c, new String[] { cipherSuite3 }, null)); 236 assertSSLSessionContextSize(2, c); 237 238 for (SSLSocket[] pair : toClose) { 239 for (SSLSocket s : pair) { 240 s.close(); 241 } 242 } 243 c.close(); 244 } 245 246 public void test_SSLSessionContext_getSessionTimeout() { 247 TestSSLContext c = TestSSLContext.create(); 248 assertEquals(TestSSLContext.EXPECTED_DEFAULT_SSL_SESSION_CACHE_TIMEOUT, 249 c.clientContext.getClientSessionContext().getSessionTimeout()); 250 assertEquals(TestSSLContext.EXPECTED_DEFAULT_SSL_SESSION_CACHE_TIMEOUT, 251 c.serverContext.getServerSessionContext().getSessionTimeout()); 252 c.close(); 253 254 TestSSLSocketPair s = TestSSLSocketPair.create(); 255 assertEquals(TestSSLContext.EXPECTED_DEFAULT_SSL_SESSION_CACHE_TIMEOUT, 256 s.c.clientContext.getClientSessionContext().getSessionTimeout()); 257 assertEquals(TestSSLContext.EXPECTED_DEFAULT_SSL_SESSION_CACHE_TIMEOUT, 258 s.c.serverContext.getServerSessionContext().getSessionTimeout()); 259 s.close(); 260 } 261 262 public void test_SSLSessionContext_setSessionTimeout() throws Exception { 263 TestSSLContext c = TestSSLContext.create(); 264 assertEquals(TestSSLContext.EXPECTED_DEFAULT_SSL_SESSION_CACHE_TIMEOUT, 265 c.clientContext.getClientSessionContext().getSessionTimeout()); 266 assertEquals(TestSSLContext.EXPECTED_DEFAULT_SSL_SESSION_CACHE_TIMEOUT, 267 c.serverContext.getServerSessionContext().getSessionTimeout()); 268 c.clientContext.getClientSessionContext().setSessionTimeout(0); 269 c.serverContext.getServerSessionContext().setSessionTimeout(0); 270 assertEquals(0, c.clientContext.getClientSessionContext().getSessionTimeout()); 271 assertEquals(0, c.serverContext.getServerSessionContext().getSessionTimeout()); 272 273 try { 274 c.clientContext.getClientSessionContext().setSessionTimeout(-1); 275 fail(); 276 } catch (IllegalArgumentException expected) { 277 } 278 try { 279 c.serverContext.getServerSessionContext().setSessionTimeout(-1); 280 fail(); 281 } catch (IllegalArgumentException expected) { 282 } 283 c.close(); 284 285 TestSSLSocketPair s = TestSSLSocketPair.create(); 286 assertSSLSessionContextSize(1, s.c); 287 Thread.sleep(1 * 1000); 288 s.c.clientContext.getClientSessionContext().setSessionTimeout(1); 289 s.c.serverContext.getServerSessionContext().setSessionTimeout(1); 290 assertSSLSessionContextSize(0, s.c); 291 s.close(); 292 } 293} 294