1 /* 2 * Copyright (C) 2007 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 package tests.api.javax.net.ssl; 17 18 import dalvik.annotation.AndroidOnly; 19 import java.io.ByteArrayInputStream; 20 import java.io.IOException; 21 import java.io.InputStream; 22 import java.net.InetAddress; 23 import java.net.InetSocketAddress; 24 import java.net.UnknownHostException; 25 import java.security.KeyStore; 26 import java.security.SecureRandom; 27 import java.util.Arrays; 28 import javax.net.ssl.HandshakeCompletedEvent; 29 import javax.net.ssl.HandshakeCompletedListener; 30 import javax.net.ssl.KeyManager; 31 import javax.net.ssl.KeyManagerFactory; 32 import javax.net.ssl.SSLContext; 33 import javax.net.ssl.SSLServerSocket; 34 import javax.net.ssl.SSLSocket; 35 import javax.net.ssl.SSLSocketFactory; 36 import javax.net.ssl.TrustManager; 37 import javax.security.cert.X509Certificate; 38 import junit.framework.TestCase; 39 import libcore.io.Base64; 40 import tests.api.javax.net.ssl.HandshakeCompletedEventTest.TestTrustManager; 41 import tests.support.Support_PortManager; 42 import libcore.java.security.StandardNames; 43 44 public class SSLSocketTest extends TestCase { 45 46 public class HandshakeCL implements HandshakeCompletedListener { 47 public void handshakeCompleted(HandshakeCompletedEvent event) { 48 } 49 } 50 51 /** 52 * javax.net.ssl.SSLSocket#SSLSocket() 53 */ 54 public void testConstructor_01() throws Exception { 55 SSLSocket ssl = getSSLSocket(); 56 assertNotNull(ssl); 57 ssl.close(); 58 } 59 60 /** 61 * javax.net.ssl.SSLSocket#SSLSocket(InetAddress address, int port) 62 */ 63 public void testConstructor_02() throws UnknownHostException, IOException { 64 int sport = startServer("Cons InetAddress,I"); 65 int[] invalidPort = {-1, Integer.MIN_VALUE, 65536, Integer.MAX_VALUE}; 66 67 SSLSocket ssl = getSSLSocket(InetAddress.getLocalHost(), sport); 68 assertNotNull(ssl); 69 assertEquals(sport, ssl.getPort()); 70 ssl.close(); 71 72 try { 73 getSSLSocket(InetAddress.getLocalHost(), sport + 1); 74 fail(); 75 } catch (IOException expected) { 76 } 77 78 for (int i = 0; i < invalidPort.length; i++) { 79 try { 80 getSSLSocket(InetAddress.getLocalHost(), invalidPort[i]); 81 fail(); 82 } catch (IllegalArgumentException expected) { 83 } 84 } 85 } 86 87 /** 88 * javax.net.ssl.SSLSocket#SSLSocket(InetAddress address, int port, 89 * InetAddress clientAddress, int clientPort) 90 */ 91 public void testConstructor_03() throws UnknownHostException, IOException { 92 int sport = startServer("Cons InetAddress,I,InetAddress,I"); 93 int portNumber = Support_PortManager.getNextPort(); 94 95 SSLSocket ssl = getSSLSocket(InetAddress.getLocalHost(), sport, 96 InetAddress.getLocalHost(), portNumber); 97 assertNotNull(ssl); 98 assertEquals(sport, ssl.getPort()); 99 assertEquals(portNumber, ssl.getLocalPort()); 100 ssl.close(); 101 102 try { 103 getSSLSocket(InetAddress.getLocalHost(), 8081, InetAddress.getLocalHost(), 8082); 104 fail(); 105 } catch (IOException expected) { 106 } 107 108 try { 109 getSSLSocket(InetAddress.getLocalHost(), -1, InetAddress.getLocalHost(), sport + 1); 110 fail(); 111 } catch (IllegalArgumentException expected) { 112 } 113 try { 114 getSSLSocket(InetAddress.getLocalHost(), sport, InetAddress.getLocalHost(), -1); 115 fail(); 116 } catch (IllegalArgumentException expected) { 117 } 118 119 try { 120 getSSLSocket(InetAddress.getLocalHost(), Integer.MIN_VALUE, 121 InetAddress.getLocalHost(), sport + 1); 122 fail(); 123 } catch (IOException expectedOnRI) { 124 assertTrue(StandardNames.IS_RI); 125 } catch (IllegalArgumentException expectedOnAndroid) { 126 assertFalse(StandardNames.IS_RI); 127 } 128 try { 129 getSSLSocket(InetAddress.getLocalHost(), sport, 130 InetAddress.getLocalHost(), Integer.MAX_VALUE); 131 fail(); 132 } catch (IllegalArgumentException expectedOnAndroid) { 133 assertFalse(StandardNames.IS_RI); 134 } 135 } 136 137 /** 138 * javax.net.ssl.SSLSocket#SSLSocket(String host, int port) 139 */ 140 public void testConstructor_04() throws UnknownHostException, IOException { 141 int sport = startServer("Cons String,I"); 142 int[] invalidPort = {-1, Integer.MIN_VALUE, 65536, Integer.MAX_VALUE}; 143 144 SSLSocket ssl = getSSLSocket(InetAddress.getLocalHost().getHostName(), sport); 145 assertNotNull(ssl); 146 assertEquals(sport, ssl.getPort()); 147 ssl.close(); 148 149 try { 150 getSSLSocket("localhost", 8082); 151 fail(); 152 } catch (IOException expected) { 153 } 154 155 for (int i = 0; i < invalidPort.length; i++) { 156 try { 157 getSSLSocket(InetAddress.getLocalHost().getHostName(), invalidPort[i]); 158 fail(); 159 } catch (IllegalArgumentException expected) { 160 } 161 } 162 163 try { 164 getSSLSocket("bla-bla", sport); 165 fail(); 166 } catch (UnknownHostException expected) { 167 } 168 } 169 170 /** 171 * javax.net.ssl.SSLSocket#SSLSocket(String host, int port, InetAddress clientAddress, 172 * int clientPort) 173 */ 174 public void testConstructor_05() throws UnknownHostException, IOException { 175 int sport = startServer("Cons String,I,InetAddress,I"); 176 int portNumber = Support_PortManager.getNextPort(); 177 int[] invalidPort = {-1, Integer.MIN_VALUE, 65536, Integer.MAX_VALUE}; 178 179 SSLSocket ssl = getSSLSocket(InetAddress.getLocalHost().getHostName(), sport, 180 InetAddress.getLocalHost(), portNumber); 181 assertNotNull(ssl); 182 assertEquals(sport, ssl.getPort()); 183 assertEquals(portNumber, ssl.getLocalPort()); 184 185 try { 186 getSSLSocket("localhost", 8081, InetAddress.getLocalHost(), 8082); 187 fail(); 188 } catch (IOException expected) { 189 } 190 191 for (int i = 0; i < invalidPort.length; i++) { 192 portNumber = Support_PortManager.getNextPort(); 193 try { 194 getSSLSocket(InetAddress.getLocalHost().getHostName(), invalidPort[i], 195 InetAddress.getLocalHost(), portNumber); 196 fail(); 197 } catch (IllegalArgumentException expected) { 198 } 199 try { 200 getSSLSocket(InetAddress.getLocalHost().getHostName(), sport, 201 InetAddress.getLocalHost(), invalidPort[i]); 202 fail(); 203 } catch (IllegalArgumentException expected) { 204 } 205 } 206 207 portNumber = Support_PortManager.getNextPort(); 208 try { 209 getSSLSocket("bla-bla", sport, InetAddress.getLocalHost(), portNumber); 210 fail(); 211 } catch (UnknownHostException expected) { 212 } 213 } 214 215 public void test_creationStressTest() throws Exception { 216 // Test the default codepath, which uses /dev/urandom. 217 SSLContext sslContext = SSLContext.getInstance("TLS"); 218 sslContext.init(null, null, null); 219 for (int i = 0; i < 2048; ++i) { 220 sslContext.getSocketFactory().createSocket().close(); 221 } 222 223 // Test the other codepath, which copies a seed from a byte[]. 224 sslContext.init(null, null, new SecureRandom()); 225 for (int i = 0; i < 2048; ++i) { 226 sslContext.getSocketFactory().createSocket().close(); 227 } 228 } 229 230 /** 231 * javax.net.ssl.SSLSocket#addHandshakeCompletedListener(HandshakeCompletedListener listener) 232 */ 233 @AndroidOnly("RI doesn't throw the specified IAE") 234 public void test_addHandshakeCompletedListener() throws IOException { 235 SSLSocket ssl = getSSLSocket(); 236 HandshakeCompletedListener ls = new HandshakeCL(); 237 try { 238 ssl.addHandshakeCompletedListener(null); 239 fail(); 240 } catch (IllegalArgumentException expected) { 241 } 242 ssl.addHandshakeCompletedListener(ls); 243 ssl.close(); 244 } 245 246 /** 247 * javax.net.ssl.SSLSocket#removeHandshakeCompletedListener(HandshakeCompletedListener listener) 248 */ 249 public void test_removeHandshakeCompletedListener() throws IOException { 250 SSLSocket ssl = getSSLSocket(); 251 HandshakeCompletedListener ls = new HandshakeCL(); 252 try { 253 ssl.removeHandshakeCompletedListener(null); 254 fail(); 255 } catch (IllegalArgumentException expected) { 256 } 257 258 try { 259 ssl.removeHandshakeCompletedListener(ls); 260 } catch (IllegalArgumentException expected) { 261 } 262 263 ssl.addHandshakeCompletedListener(ls); 264 ssl.removeHandshakeCompletedListener(ls); 265 ssl.close(); 266 } 267 268 /** 269 * javax.net.ssl.SSLSocket#setEnableSessionCreation(boolean flag) 270 * javax.net.ssl.SSLSocket#getEnableSessionCreation() 271 */ 272 public void test_EnableSessionCreation() throws IOException { 273 SSLSocket ssl = getSSLSocket(); 274 assertTrue(ssl.getEnableSessionCreation()); 275 ssl.setEnableSessionCreation(false); 276 assertFalse(ssl.getEnableSessionCreation()); 277 ssl.setEnableSessionCreation(true); 278 assertTrue(ssl.getEnableSessionCreation()); 279 ssl.close(); 280 } 281 282 /** 283 * javax.net.ssl.SSLSocket#setNeedClientAuth(boolean need) 284 * javax.net.ssl.SSLSocket#getNeedClientAuthCreation() 285 */ 286 public void test_NeedClientAuth() throws UnknownHostException, IOException { 287 SSLSocket ssl = getSSLSocket(); 288 ssl.setNeedClientAuth(true); 289 assertTrue(ssl.getNeedClientAuth()); 290 ssl.setNeedClientAuth(false); 291 assertFalse(ssl.getNeedClientAuth()); 292 ssl.close(); 293 } 294 295 /** 296 * javax.net.ssl.SSLSocket#setWantClientAuth(boolean want) 297 * javax.net.ssl.SSLSocket#getWantClientAuthCreation() 298 */ 299 public void test_WantClientAuth() throws UnknownHostException, IOException { 300 SSLSocket ssl = getSSLSocket(); 301 ssl.setWantClientAuth(true); 302 assertTrue(ssl.getWantClientAuth()); 303 ssl.setWantClientAuth(false); 304 assertFalse(ssl.getWantClientAuth()); 305 ssl.close(); 306 } 307 308 /** 309 * javax.net.ssl.SSLSocket#getSupportedProtocols() 310 */ 311 public void test_getSupportedProtocols() throws IOException { 312 SSLSocket ssl = getSSLSocket(); 313 String[] res = ssl.getSupportedProtocols(); 314 assertTrue("No supported protocols found", res.length > 0); 315 ssl.close(); 316 } 317 318 /** 319 * javax.net.ssl.SSLSocket#getEnabledProtocols() 320 * javax.net.ssl.SSLSocket#setEnabledProtocols(String[] protocols) 321 */ 322 public void test_EnabledProtocols() throws IOException { 323 SSLSocket ssl = getSSLSocket(); 324 try { 325 ssl.setEnabledProtocols(null); 326 fail(); 327 } catch (IllegalArgumentException expected) { 328 } 329 ssl.setEnabledProtocols(new String[] {}); 330 try { 331 ssl.setEnabledProtocols(new String[] {"blubb"}); 332 fail(); 333 } catch (IllegalArgumentException expected) { 334 } 335 ssl.setEnabledProtocols(ssl.getEnabledProtocols()); 336 String[] res = ssl.getEnabledProtocols(); 337 assertEquals("no enabled protocols set", 338 ssl.getEnabledProtocols().length, res.length); 339 ssl.close(); 340 } 341 342 /** 343 * javax.net.ssl.SSLSocket#getSession() 344 */ 345 public void test_getSession() throws IOException { 346 SSLSocket ssl = getSSLSocket(); 347 assertNotNull(ssl.getSession()); 348 ssl.close(); 349 } 350 351 /** 352 * javax.net.ssl.SSLSocket#getSupportedCipherSuites() 353 */ 354 public void test_getSupportedCipherSuites() throws IOException { 355 SSLSocket ssl = getSSLSocket(); 356 String[] res = ssl.getSupportedCipherSuites(); 357 assertTrue("no supported cipher suites", res.length > 0); 358 ssl.close(); 359 } 360 361 /** 362 * javax.net.ssl.SSLSocket#getEnabledCipherSuites() 363 * javax.net.ssl.SSLSocket#setEnabledCipherSuites(String[] suites) 364 */ 365 public void test_EnabledCipherSuites() throws IOException { 366 SSLSocket ssl = getSSLSocket(); 367 try { 368 ssl.setEnabledCipherSuites(null); 369 fail(); 370 } catch (IllegalArgumentException expected) { 371 } 372 ssl.setEnabledCipherSuites(new String[] {}); 373 try { 374 ssl.setEnabledCipherSuites(new String[] {"blubb"}); 375 fail(); 376 } catch (IllegalArgumentException expected) { 377 } 378 ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites()); 379 String[] res = ssl.getEnabledCipherSuites(); 380 assertNotNull("NULL result", res); 381 assertEquals("not all supported cipher suites were enabled", 382 Arrays.asList(ssl.getSupportedCipherSuites()), 383 Arrays.asList(res)); 384 ssl.close(); 385 } 386 387 /** 388 * javax.net.ssl.SSLSocket#getUseClientMode() 389 * javax.net.ssl.SSLSocket#setUseClientMode(boolean mode) 390 */ 391 public void test_UseClientMode() throws IOException { 392 SSLSocket ssl = getSSLSocket(); 393 assertTrue(ssl.getUseClientMode()); 394 ssl.setUseClientMode(false); 395 assertFalse(ssl.getUseClientMode()); 396 ssl.close(); 397 398 ssl = getSSLSocket("localhost", startServer("UseClientMode")); 399 try { 400 ssl.startHandshake(); 401 } catch (IOException ioe) { 402 //fail(ioe + " was thrown for method startHandshake()"); 403 } 404 try { 405 ssl.setUseClientMode(false); 406 fail(); 407 } catch (IllegalArgumentException expected) { 408 } 409 ssl.close(); 410 } 411 412 /** 413 * javax.net.ssl.SSLSocket#startHandshake() 414 */ 415 public void test_startHandshake() throws IOException { 416 SSLSocket ssl = getSSLSocket(); 417 try { 418 ssl.startHandshake(); 419 fail(); 420 } catch (IOException expected) { 421 } 422 ssl.close(); 423 } 424 425 boolean useBKS = !StandardNames.IS_RI; 426 427 private String PASSWORD = "android"; 428 429 private int port = Support_PortManager.getNextPort(); 430 431 private boolean serverReady = false; 432 433 /** 434 * Defines the keystore contents for the server, BKS version. Holds just a 435 * single self-generated key. The subject name is "Test Server". 436 */ 437 private static final String SERVER_KEYS_BKS = "" 438 + "AAAAAQAAABQDkebzoP1XwqyWKRCJEpn/t8dqIQAABDkEAAVteWtleQAAARpYl20nAAAAAQAFWC41" 439 + "MDkAAAJNMIICSTCCAbKgAwIBAgIESEfU1jANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJVUzET" 440 + "MBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNV" 441 + "BAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMB4XDTA4MDYwNTExNTgxNFoXDTA4MDkw" 442 + "MzExNTgxNFowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01U" 443 + "VjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRQwEgYDVQQDEwtUZXN0IFNlcnZl" 444 + "cjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0LIdKaIr9/vsTq8BZlA3R+NFWRaH4lGsTAQy" 445 + "DPMF9ZqEDOaL6DJuu0colSBBBQ85hQTPa9m9nyJoN3pEi1hgamqOvQIWcXBk+SOpUGRZZFXwniJV" 446 + "zDKU5nE9MYgn2B9AoiH3CSuMz6HRqgVaqtppIe1jhukMc/kHVJvlKRNy9XMCAwEAATANBgkqhkiG" 447 + "9w0BAQUFAAOBgQC7yBmJ9O/eWDGtSH9BH0R3dh2NdST3W9hNZ8hIa8U8klhNHbUCSSktZmZkvbPU" 448 + "hse5LI3dh6RyNDuqDrbYwcqzKbFJaq/jX9kCoeb3vgbQElMRX8D2ID1vRjxwlALFISrtaN4VpWzV" 449 + "yeoHPW4xldeZmoVtjn8zXNzQhLuBqX2MmAAAAqwAAAAUvkUScfw9yCSmALruURNmtBai7kQAAAZx" 450 + "4Jmijxs/l8EBaleaUru6EOPioWkUAEVWCxjM/TxbGHOi2VMsQWqRr/DZ3wsDmtQgw3QTrUK666sR" 451 + "MBnbqdnyCyvM1J2V1xxLXPUeRBmR2CXorYGF9Dye7NkgVdfA+9g9L/0Au6Ugn+2Cj5leoIgkgApN" 452 + "vuEcZegFlNOUPVEs3SlBgUF1BY6OBM0UBHTPwGGxFBBcetcuMRbUnu65vyDG0pslT59qpaR0TMVs" 453 + "P+tcheEzhyjbfM32/vwhnL9dBEgM8qMt0sqF6itNOQU/F4WGkK2Cm2v4CYEyKYw325fEhzTXosck" 454 + "MhbqmcyLab8EPceWF3dweoUT76+jEZx8lV2dapR+CmczQI43tV9btsd1xiBbBHAKvymm9Ep9bPzM" 455 + "J0MQi+OtURL9Lxke/70/MRueqbPeUlOaGvANTmXQD2OnW7PISwJ9lpeLfTG0LcqkoqkbtLKQLYHI" 456 + "rQfV5j0j+wmvmpMxzjN3uvNajLa4zQ8l0Eok9SFaRr2RL0gN8Q2JegfOL4pUiHPsh64WWya2NB7f" 457 + "V+1s65eA5ospXYsShRjo046QhGTmymwXXzdzuxu8IlnTEont6P4+J+GsWk6cldGbl20hctuUKzyx" 458 + "OptjEPOKejV60iDCYGmHbCWAzQ8h5MILV82IclzNViZmzAapeeCnexhpXhWTs+xDEYSKEiG/camt" 459 + "bhmZc3BcyVJrW23PktSfpBQ6D8ZxoMfF0L7V2GQMaUg+3r7ucrx82kpqotjv0xHghNIm95aBr1Qw" 460 + "1gaEjsC/0wGmmBDg1dTDH+F1p9TInzr3EFuYD0YiQ7YlAHq3cPuyGoLXJ5dXYuSBfhDXJSeddUkl" 461 + "k1ufZyOOcskeInQge7jzaRfmKg3U94r+spMEvb0AzDQVOKvjjo1ivxMSgFRZaDb/4qw="; 462 463 /** 464 * Defines the keystore contents for the server, JKS version. Holds just a 465 * single self-generated key. The subject name is "Test Server". 466 */ 467 private static final String SERVER_KEYS_JKS = "" 468 + "/u3+7QAAAAIAAAABAAAAAQAFbXlrZXkAAAEaWFfBeAAAArowggK2MA4GCisGAQQBKgIRAQEFAASC" 469 + "AqI2kp5XjnF8YZkhcF92YsJNQkvsmH7zqMM87j23zSoV4DwyE3XeC/gZWq1ToScIhoqZkzlbWcu4" 470 + "T/Zfc/DrfGk/rKbBL1uWKGZ8fMtlZk8KoAhxZk1JSyJvdkyKxqmzUbxk1OFMlN2VJNu97FPVH+du" 471 + "dvjTvmpdoM81INWBW/1fZJeQeDvn4mMbbe0IxgpiLnI9WSevlaDP/sm1X3iO9yEyzHLL+M5Erspo" 472 + "Cwa558fOu5DdsICMXhvDQxjWFKFhPHnKtGe+VvwkG9/bAaDgx3kfhk0w5zvdnkKb+8Ed9ylNRzdk" 473 + "ocAa/mxlMTOsTvDKXjjsBupNPIIj7OP4GNnZaxkJjSs98pEO67op1GX2qhy6FSOPNuq8k/65HzUc" 474 + "PYn6voEeh6vm02U/sjEnzRevQ2+2wXoAdp0EwtQ/DlMe+NvcwPGWKuMgX4A4L93DZGb04N2VmAU3" 475 + "YLOtZwTO0LbuWrcCM/q99G/7LcczkxIVrO2I/rh8RXVczlf9QzcrFObFv4ATuspWJ8xG7DhsMbnk" 476 + "rT94Pq6TogYeoz8o8ZMykesAqN6mt/9+ToIemmXv+e+KU1hI5oLwWMnUG6dXM6hIvrULY6o+QCPH" 477 + "172YQJMa+68HAeS+itBTAF4Clm/bLn6reHCGGU6vNdwU0lYldpiOj9cB3t+u2UuLo6tiFWjLf5Zs" 478 + "EQJETd4g/EK9nHxJn0GAKrWnTw7pEHQJ08elzUuy04C/jEEG+4QXU1InzS4o/kR0Sqz2WTGDoSoq" 479 + "ewuPRU5bzQs/b9daq3mXrnPtRBL6HfSDAdpTK76iHqLCGdqx3avHjVSBm4zFvEuYBCev+3iKOBmg" 480 + "yh7eQRTjz4UOWfy85omMBr7lK8PtfVBDzOXpasxS0uBgdUyBDX4tO6k9jZ8a1kmQRQAAAAEABVgu" 481 + "NTA5AAACSDCCAkQwggGtAgRIR8SKMA0GCSqGSIb3DQEBBAUAMGkxCzAJBgNVBAYTAlVTMRMwEQYD" 482 + "VQQIEwpDYWxpZm9ybmlhMQwwCgYDVQQHEwNNVFYxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMH" 483 + "QW5kcm9pZDEUMBIGA1UEAxMLVGVzdCBTZXJ2ZXIwHhcNMDgwNjA1MTA0ODQyWhcNMDgwOTAzMTA0" 484 + "ODQyWjBpMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8w" 485 + "DQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMIGf" 486 + "MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwoC6chqCI84rj1PrXuJgbiit4EV909zR6N0jNlYfg" 487 + "itwB39bP39wH03rFm8T59b3mbSptnGmCIpLZn25KPPFsYD3JJ+wFlmiUdEP9H05flfwtFQJnw9uT" 488 + "3rRIdYVMPcQ3RoZzwAMliGr882I2thIDbA6xjGU/1nRIdvk0LtxH3QIDAQABMA0GCSqGSIb3DQEB" 489 + "BAUAA4GBAJn+6YgUlY18Ie+0+Vt8oEi81DNi/bfPrAUAh63fhhBikx/3R9dl3wh09Z6p7cIdNxjW" 490 + "n2ll+cRW9eqF7z75F0Omm0C7/KAEPjukVbszmzeU5VqzkpSt0j84YWi+TfcHRrfvhLbrlmGITVpY" 491 + "ol5pHLDyqGmDs53pgwipWqsn/nEXEBgj3EoqPeqHbDf7YaP8h/5BSt0="; 492 493 protected int startServer(String name) { 494 String keys = useBKS ? SERVER_KEYS_BKS : SERVER_KEYS_JKS; 495 TestServer server = new TestServer(true, keys); 496 Thread serverThread = new Thread(server); 497 serverThread.start(); 498 try { 499 while (!serverReady) { 500 Exception e = server.getException(); 501 if (e != null) { 502 throw new AssertionError(e); 503 } 504 Thread.currentThread().sleep(50); 505 } 506 // give the server 100 millis to accept 507 Thread.currentThread().sleep(100); 508 } catch (InterruptedException ignore) { 509 } 510 return server.sport; 511 } 512 513 /** 514 * Implements a test SSL socket server. It wait for a connection on a given 515 * port, requests client authentication (if specified), and read 256 bytes 516 * from the socket. 517 */ 518 class TestServer implements Runnable { 519 520 public static final int CLIENT_AUTH_NONE = 0; 521 522 public static final int CLIENT_AUTH_WANTED = 1; 523 524 public static final int CLIENT_AUTH_NEEDED = 2; 525 526 private TestTrustManager trustManager; 527 528 private Exception exception; 529 530 String keys; 531 532 private boolean provideKeys; 533 534 int sport; 535 536 public TestServer(boolean provideKeys, String keys) { 537 this.keys = keys; 538 this.provideKeys = provideKeys; 539 540 trustManager = new TestTrustManager(); 541 } 542 543 public void run() { 544 try { 545 KeyManager[] keyManagers = provideKeys ? getKeyManagers(keys) : null; 546 TrustManager[] trustManagers = new TrustManager[] { trustManager }; 547 548 SSLContext sslContext = SSLContext.getInstance("TLS"); 549 sslContext.init(keyManagers, trustManagers, null); 550 551 SSLServerSocket serverSocket = (SSLServerSocket) 552 sslContext.getServerSocketFactory().createServerSocket(); 553 try { 554 serverSocket.bind(new InetSocketAddress(port)); 555 sport = serverSocket.getLocalPort(); 556 serverReady = true; 557 558 SSLSocket clientSocket = (SSLSocket)serverSocket.accept(); 559 560 try { 561 InputStream stream = clientSocket.getInputStream(); 562 try { 563 for (int i = 0; i < 256; i++) { 564 int j = stream.read(); 565 if (i != j) { 566 throw new RuntimeException("Error reading socket, expected " + i 567 + ", got " + j); 568 } 569 } 570 } finally { 571 stream.close(); 572 } 573 } finally { 574 clientSocket.close(); 575 } 576 } finally { 577 serverSocket.close(); 578 } 579 } catch (Exception ex) { 580 exception = ex; 581 } 582 } 583 584 public Exception getException() { 585 return exception; 586 } 587 588 public X509Certificate[] getChain() { 589 return trustManager.getChain(); 590 } 591 592 } 593 594 /** 595 * Loads a keystore from a base64-encoded String. Returns the KeyManager[] 596 * for the result. 597 */ 598 private KeyManager[] getKeyManagers(String keys) throws Exception { 599 byte[] bytes = Base64.decode(keys.getBytes()); 600 InputStream inputStream = new ByteArrayInputStream(bytes); 601 602 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 603 keyStore.load(inputStream, PASSWORD.toCharArray()); 604 inputStream.close(); 605 606 String algorithm = KeyManagerFactory.getDefaultAlgorithm(); 607 KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(algorithm); 608 keyManagerFactory.init(keyStore, PASSWORD.toCharArray()); 609 610 return keyManagerFactory.getKeyManagers(); 611 } 612 613 private SSLSocket getSSLSocket() throws IOException { 614 return (SSLSocket) SSLSocketFactory.getDefault().createSocket(); 615 } 616 617 private SSLSocket getSSLSocket(InetAddress host, int port) throws IOException { 618 return (SSLSocket) SSLSocketFactory.getDefault().createSocket(host, port); 619 } 620 621 private SSLSocket getSSLSocket(String host, int port) throws UnknownHostException, IOException { 622 return (SSLSocket) SSLSocketFactory.getDefault().createSocket(host, port); 623 } 624 625 private SSLSocket getSSLSocket(InetAddress host, int port, InetAddress localHost, int localPort) 626 throws IOException { 627 return (SSLSocket) SSLSocketFactory.getDefault().createSocket(host, 628 port, 629 localHost, 630 localPort); 631 } 632 633 private SSLSocket getSSLSocket(String host, int port, InetAddress localHost, int localPort) 634 throws UnknownHostException, IOException { 635 return (SSLSocket) SSLSocketFactory.getDefault().createSocket(host, 636 port, 637 localHost, 638 localPort); 639 } 640 } 641