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