SSLSessionTest.java revision f33eae7e84eb6d3b0f4e86b59605bb3de73009f3
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package tests.api.javax.net.ssl; 19 20import dalvik.annotation.AndroidOnly; 21import dalvik.annotation.KnownFailure; 22import dalvik.annotation.TestLevel; 23import dalvik.annotation.TestTargetClass; 24import dalvik.annotation.TestTargetNew; 25import dalvik.annotation.TestTargets; 26 27import junit.framework.TestCase; 28 29import org.apache.harmony.luni.util.Base64; 30 31import tests.api.javax.net.ssl.HandshakeCompletedEventTest.MyHandshakeListener; 32import tests.api.javax.net.ssl.HandshakeCompletedEventTest.TestTrustManager; 33import tests.support.Support_PortManager; 34 35import java.io.ByteArrayInputStream; 36import java.io.InputStream; 37import java.io.OutputStream; 38import java.net.InetAddress; 39import java.net.InetSocketAddress; 40import java.security.KeyStore; 41import java.security.Principal; 42import java.security.cert.Certificate; 43import java.util.Date; 44 45import javax.net.ssl.KeyManager; 46import javax.net.ssl.KeyManagerFactory; 47import javax.net.ssl.SSLContext; 48import javax.net.ssl.SSLPeerUnverifiedException; 49import javax.net.ssl.SSLServerSocket; 50import javax.net.ssl.SSLSession; 51import javax.net.ssl.SSLSocket; 52import javax.net.ssl.SSLSessionBindingEvent; 53import javax.net.ssl.SSLSessionBindingListener; 54import javax.net.ssl.TrustManager; 55import javax.security.cert.X509Certificate; 56 57/** 58 * Tests for SSLSession class 59 * 60 */ 61@TestTargetClass(SSLSession.class) 62public class SSLSessionTest extends TestCase { 63 64 // set to true if on Android, false if on RI 65 boolean useBKS = true; 66 67 /** 68 * @tests javax.net.ssl.SSLSession#getPeerHost() 69 * @tests javax.net.ssl.SSLSession#getPeerPort() 70 */ 71 @TestTargets({ 72 @TestTargetNew( 73 level = TestLevel.COMPLETE, 74 notes = "", 75 method = "getPeerHost", 76 args = {} 77 ), 78 @TestTargetNew( 79 level = TestLevel.COMPLETE, 80 notes = "", 81 method = "getPeerPort", 82 args = {} 83 ) 84 }) 85 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 86 public void test_getPeerHost() { 87 SSLSession s = clientSession; 88 try { 89 assertEquals(s.getPeerHost(), InetAddress.getLocalHost().getHostName()); 90 assertEquals(s.getPeerPort(), port); 91 } catch (Exception ex) { 92 fail("Unexpected exception " + ex); 93 } 94 } 95 96 /** 97 * @tests javax.net.ssl.SSLSession#invalidate() 98 * @tests javax.net.ssl.SSLSession#isValid() 99 */ 100 @TestTargets({ 101 @TestTargetNew( 102 level = TestLevel.COMPLETE, 103 notes = "", 104 method = "invalidate", 105 args = {} 106 ), 107 @TestTargetNew( 108 level = TestLevel.COMPLETE, 109 notes = "", 110 method = "isValid", 111 args = {} 112 ) 113 }) 114 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 115 public void test_invalidate() { 116 SSLSession s = clientSession; 117 try { 118 assertTrue(s.isValid()); 119 s.invalidate(); 120 assertFalse(s.isValid()); 121 } catch (Exception ex) { 122 fail("Unexpected exception " + ex); 123 } 124 } 125 126 /** 127 * @tests javax.net.ssl.SSLSession#getPeerPrincipal() 128 */ 129 @TestTargetNew( 130 level = TestLevel.SUFFICIENT, 131 notes = "Exception wasn't implemented in the interface's class", 132 method = "getPeerPrincipal", 133 args = {} 134 ) 135 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 136 public void test_getPeerPrincipal() { 137 try { 138 Principal p1 = clientSession.getPeerPrincipal(); 139 KeyStore store = server.getStore(); 140 Certificate cert = store.getCertificate("mykey"); 141 X509Certificate c = X509Certificate.getInstance(cert.getEncoded()); 142 Principal p2 = c.getSubjectDN(); 143 String name2 = p2.getName().replaceAll(" ", ""); 144 String name1 = p1.getName().replaceAll(" ", ""); 145 assertEquals(name2, name1); 146 } catch (Exception ex) { 147 fail("Unexpected exception " + ex); 148 } 149 } 150 151 /** 152 * @tests javax.net.ssl.SSLSession#getApplicationBufferSize() 153 */ 154 @TestTargetNew( 155 level = TestLevel.COMPLETE, 156 notes = "", 157 method = "getApplicationBufferSize", 158 args = {} 159 ) 160 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 161 public void test_getApplicationBufferSize() { 162 try { 163 assertTrue(clientSession.getApplicationBufferSize() > 0); 164 } catch (Exception ex) { 165 fail("Unexpected exception " + ex); 166 } 167 } 168 169 /** 170 * @tests javax.net.ssl.SSLSession#getCipherSuite() 171 */ 172 @TestTargetNew( 173 level = TestLevel.COMPLETE, 174 notes = "", 175 method = "getCipherSuite", 176 args = {} 177 ) 178 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 179 public void test_getCipherSuite() { 180 try { 181 assertEquals(cipherSuite, clientSession.getCipherSuite()); 182 } catch (Exception ex) { 183 fail("Unexpected exception " + ex); 184 } 185 } 186 187 /** 188 * @tests javax.net.ssl.SSLSession#getCreationTime() 189 */ 190 @TestTargetNew( 191 level = TestLevel.COMPLETE, 192 notes = "", 193 method = "getCreationTime", 194 args = {} 195 ) 196 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 197 public void test_getCreationTime() { 198 try { 199 // check if creation time was in the last 10 seconds 200 long currentTime = System.currentTimeMillis(); 201 long sessionTime = clientSession.getCreationTime(); 202 long diff = currentTime - sessionTime; 203 assertTrue("diff between " + currentTime + " and " + sessionTime + " should be < 10000", diff < 10000); 204 } catch (Exception ex) { 205 fail("Unexpected exception " + ex); 206 } 207 } 208 209 /** 210 * @tests javax.net.ssl.SSLSession#getId() 211 */ 212 @TestTargetNew( 213 level = TestLevel.COMPLETE, 214 notes = "", 215 method = "getId", 216 args = {} 217 ) 218 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 219 public void test_getId() { 220 byte[] id = clientSession.getId(); 221 try { 222 SSLSession sess = 223 clientSslContext.getClientSessionContext().getSession(id); 224 assertNotNull("Could not find session for id " + id, sess); 225 assertEquals(clientSession, sess); 226 } catch (Exception ex) { 227 fail("Unexpected exception " + ex); 228 } 229 } 230 231 /** 232 * @tests javax.net.ssl.SSLSession#getLastAccessedTime() 233 */ 234 @TestTargetNew( 235 level = TestLevel.COMPLETE, 236 notes = "", 237 method = "getLastAccessedTime", 238 args = {} 239 ) 240 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 241 public void test_getLastAccessedTime() { 242 try { 243 // check if last access time was in the last 10 seconds 244 long currentTime = System.currentTimeMillis(); 245 long sessionTime = clientSession.getLastAccessedTime(); 246 long diff = currentTime - sessionTime; 247 assertTrue("diff between " + currentTime + " and " + sessionTime + " should be < 10000", diff < 10000); 248 assertTrue ("diff should be < 10000 but is " + diff, diff < 10000); 249 } catch (Exception ex) { 250 fail("Unexpected exception " + ex); 251 } 252 } 253 254 /** 255 * @tests javax.net.ssl.SSLSession#getLocalCertificates() 256 */ 257 @TestTargetNew( 258 level = TestLevel.COMPLETE, 259 notes = "", 260 method = "getLocalCertificates", 261 args = {} 262 ) 263 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 264 public void test_getLocalCertificates() { 265 try { 266 KeyStore store = client.getStore(); 267 Certificate cert = store.getCertificate("mykey"); 268 Certificate[] certs = clientSession.getLocalCertificates(); 269 assertEquals(cert, certs[0]); 270 } catch (Exception ex) { 271 fail("Unexpected exception " + ex); 272 } 273 } 274 275 /** 276 * @tests javax.net.ssl.SSLSession#getLocalPrincipal() 277 */ 278 @TestTargetNew( 279 level = TestLevel.COMPLETE, 280 notes = "", 281 method = "getLocalPrincipal", 282 args = {} 283 ) 284 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 285 public void test_getLocalPrincipal() { 286 try { 287 Principal p1 = clientSession.getLocalPrincipal(); 288 KeyStore store = client.getStore(); 289 Certificate cert = store.getCertificate("mykey"); 290 X509Certificate c = X509Certificate.getInstance(cert.getEncoded()); 291 Principal p2 = c.getSubjectDN(); 292 String name2 = p2.getName().replaceAll(" ", ""); 293 String name1 = p1.getName().replaceAll(" ", ""); 294 assertEquals(name2, name1); 295 } catch (Exception ex) { 296 fail("Unexpected exception " + ex); 297 } 298 } 299 300 /** 301 * @tests javax.net.ssl.SSLSession#getPacketBufferSize() 302 */ 303 @TestTargetNew( 304 level = TestLevel.COMPLETE, 305 notes = "", 306 method = "getPacketBufferSize", 307 args = {} 308 ) 309 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 310 public void test_getPacketBufferSize() { 311 try { 312 assertTrue(clientSession.getPacketBufferSize() > 0); 313 } catch (Exception ex) { 314 fail("Unexpected exception " + ex); 315 } 316 } 317 318 /** 319 * @tests javax.net.ssl.SSLSession#getPeerCertificates() 320 */ 321 @TestTargetNew( 322 level = TestLevel.SUFFICIENT, 323 notes = "", 324 method = "getPeerCertificates", 325 args = {} 326 ) 327 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 328 public void test_getPeerCertificates() { 329// try { 330// Certificate[] res = clientSession.getPeerCertificates(); 331// fail("SSLPeerUnverifiedException wasn't thrown"); 332// } catch (SSLPeerUnverifiedException pue) { 333// //expected 334// } 335 try { 336 Certificate[] res = clientSession.getPeerCertificates(); 337 assertTrue(res.length > 0); 338 } catch (Exception e) { 339 fail("Unexpected exception: " + e); 340 } 341 } 342 343 /** 344 * @tests javax.net.ssl.SSLSession#getPeerCertificateChain() 345 */ 346 @TestTargetNew( 347 level = TestLevel.SUFFICIENT, 348 notes = "", 349 method = "getPeerCertificateChain", 350 args = {} 351 ) 352 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 353 public void test_getPeerCertificateChain() { 354// try { 355// X509Certificate[] resN = clientSession.getPeerCertificateChain(); 356// fail("SSLPeerUnverifiedException wasn't thrown"); 357// } catch (SSLPeerUnverifiedException pue) { 358// //expected 359// } 360 try { 361 X509Certificate[] res = clientSession.getPeerCertificateChain(); 362 assertTrue(res.length > 0); 363 } catch (Exception e) { 364 fail("Unexpected exception: " + e); 365 } 366 } 367 368 /** 369 * @tests javax.net.ssl.SSLSession#getProtocol() 370 */ 371 @TestTargetNew( 372 level = TestLevel.COMPLETE, 373 notes = "", 374 method = "getProtocol", 375 args = {} 376 ) 377 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 378 public void test_getProtocol() { 379 try { 380 assertEquals(clientSession.getProtocol(), "TLSv1"); 381 } catch (Exception e) { 382 fail("Unexpected exception: " + e); 383 } 384 } 385 386 /** 387 * @tests javax.net.ssl.SSLSession#getSessionContext() 388 */ 389 @TestTargetNew( 390 level = TestLevel.COMPLETE, 391 notes = "", 392 method = "getSessionContext", 393 args = {} 394 ) 395 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 396 public void test_getSessionContext() { 397 try { 398 assertEquals(clientSslContext.getClientSessionContext(), 399 clientSession.getSessionContext()); 400 } catch (Exception e) { 401 fail("Unexpected exception: " + e); 402 } 403 } 404 405 /** 406 * @tests javax.net.ssl.SSLSession#putValue(String name, Object value) 407 * @tests javax.net.ssl.SSLSession#removeValue(String name) 408 * @tests javax.net.ssl.SSLSession#getValueNames() 409 */ 410 @TestTargets({ 411 @TestTargetNew( 412 level = TestLevel.COMPLETE, 413 notes = "", 414 method = "putValue", 415 args = {String.class, Object.class} 416 ), 417 @TestTargetNew( 418 level = TestLevel.COMPLETE, 419 notes = "", 420 method = "removeValue", 421 args = {String.class} 422 ), 423 @TestTargetNew( 424 level = TestLevel.COMPLETE, 425 notes = "", 426 method = "getValueNames", 427 args = {} 428 ) 429 }) 430 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 431 public void test_putValue() { 432 SSLSession s = clientSession; 433 mySSLSessionBindingListener sbl = new mySSLSessionBindingListener(); 434 try { 435 assertNotNull(s.getValueNames()); 436 assertEquals(s.getValueNames().length, 0); 437 s.putValue("Name_01", sbl); 438 s.putValue("Name_02", sbl); 439 s.putValue("Name_03", sbl); 440 assertEquals(s.getValueNames().length, 3); 441 s.removeValue("Name_01"); 442 assertEquals(s.getValueNames().length, 2); 443 } catch (Exception e) { 444 fail("Unexpected exception: " + e); 445 } 446 447 try { 448 s.putValue(null, null); 449 fail("IllegalArgumentException wasn't thrown"); 450 } catch (IllegalArgumentException iae) { 451 //expected 452 } 453 try { 454 s.putValue("ABC", null); 455 fail("IllegalArgumentException wasn't thrown"); 456 } catch (IllegalArgumentException iae) { 457 //expected 458 } 459 try { 460 s.putValue(null, sbl); 461 fail("IllegalArgumentException wasn't thrown"); 462 } catch (IllegalArgumentException iae) { 463 //expected 464 } 465 466 try { 467 s.removeValue(null); 468 fail("IllegalArgumentException wasn't thrown"); 469 } catch (IllegalArgumentException iae) { 470 //expected 471 } 472 } 473 474 /** 475 * @tests javax.net.ssl.SSLSession#getValue(String name) 476 */ 477 @TestTargetNew( 478 level = TestLevel.COMPLETE, 479 notes = "", 480 method = "getValue", 481 args = {String.class} 482 ) 483 @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI") 484 public void test_getValue() { 485 SSLSession s = clientSession; 486 mySSLSessionBindingListener sbl = new mySSLSessionBindingListener(); 487 488 try { 489 s.getValue(null); 490 fail("IllegalArgumentException wasn't thrown"); 491 } catch (IllegalArgumentException iae) { 492 //expected 493 } 494 495 try { 496 s.putValue("Name", sbl); 497 Object obj = s.getValue("Name"); 498 assertTrue(obj instanceof SSLSessionBindingListener); 499 } catch (Exception e) { 500 fail("Unexpected exception: " + e); 501 } 502 } 503 504 Thread serverThread, clientThread; 505 TestServer server; 506 TestClient client; 507 508 @Override 509 protected void setUp() { 510 port = Support_PortManager.getNextPort(); 511 String serverKeys = (useBKS ? SERVER_KEYS_BKS : SERVER_KEYS_JKS); 512 String clientKeys = (useBKS ? CLIENT_KEYS_BKS : CLIENT_KEYS_JKS); 513 server = new TestServer(true, 514 TestServer.CLIENT_AUTH_WANTED, serverKeys); 515 client = new TestClient(true, clientKeys); 516 517 serverThread = new Thread(server); 518 clientThread = new Thread(client); 519 520 serverThread.start(); 521 try { 522 Thread.currentThread().sleep(1000); 523 clientThread.start(); 524 } catch (InterruptedException e) { 525 fail("Could not create server or cient " + e.getMessage()); 526 } 527 while (clientSession == null 528 && server.exception == null 529 && client.exception == null) { 530 try { 531 Thread.currentThread().sleep(500); 532 } catch (InterruptedException e) { 533 fail("couldn't create session"); 534 } 535 } 536 assertNull("server thread has a pending exception: " + server.exception, 537 server.exception); 538 assertNull("client thread has a pending exception: " + client.exception, 539 client.exception); 540 assertNotNull("Could not initialize session", clientSession); 541 } 542 543 @Override 544 protected void tearDown() { 545 notFinished = false; 546 try { 547 serverThread.join(); 548 } catch (InterruptedException e) { 549 } 550 try { 551 clientThread.join(); 552 } catch (InterruptedException e) { 553 } 554 555 // The server must have completed without an exception. 556 if (server.getException() != null) { 557 throw new RuntimeException(server.getException()); 558 } 559 560 // The client must have completed without an exception. 561 if (client.getException() != null) { 562 throw new RuntimeException(client.getException()); 563 } 564 } 565 566 public class mySSLSessionBindingListener implements 567 SSLSessionBindingListener { 568 mySSLSessionBindingListener() { 569 } 570 public void valueBound(SSLSessionBindingEvent event) {} 571 public void valueUnbound(SSLSessionBindingEvent event) {} 572 } 573 574 575 576 String cipherSuiteBKS = "AES256-SHA"; 577 /** 578 * Defines the keystore contents for the server, BKS version. Holds just a 579 * single self-generated key. The subject name is "Test Server". 580 */ 581 private static final String SERVER_KEYS_BKS = 582 "AAAAAQAAABQDkebzoP1XwqyWKRCJEpn/t8dqIQAABDkEAAVteWtleQAAARpYl20nAAAAAQAFWC41" + 583 "MDkAAAJNMIICSTCCAbKgAwIBAgIESEfU1jANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJVUzET" + 584 "MBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNV" + 585 "BAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMB4XDTA4MDYwNTExNTgxNFoXDTA4MDkw" + 586 "MzExNTgxNFowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01U" + 587 "VjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRQwEgYDVQQDEwtUZXN0IFNlcnZl" + 588 "cjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0LIdKaIr9/vsTq8BZlA3R+NFWRaH4lGsTAQy" + 589 "DPMF9ZqEDOaL6DJuu0colSBBBQ85hQTPa9m9nyJoN3pEi1hgamqOvQIWcXBk+SOpUGRZZFXwniJV" + 590 "zDKU5nE9MYgn2B9AoiH3CSuMz6HRqgVaqtppIe1jhukMc/kHVJvlKRNy9XMCAwEAATANBgkqhkiG" + 591 "9w0BAQUFAAOBgQC7yBmJ9O/eWDGtSH9BH0R3dh2NdST3W9hNZ8hIa8U8klhNHbUCSSktZmZkvbPU" + 592 "hse5LI3dh6RyNDuqDrbYwcqzKbFJaq/jX9kCoeb3vgbQElMRX8D2ID1vRjxwlALFISrtaN4VpWzV" + 593 "yeoHPW4xldeZmoVtjn8zXNzQhLuBqX2MmAAAAqwAAAAUvkUScfw9yCSmALruURNmtBai7kQAAAZx" + 594 "4Jmijxs/l8EBaleaUru6EOPioWkUAEVWCxjM/TxbGHOi2VMsQWqRr/DZ3wsDmtQgw3QTrUK666sR" + 595 "MBnbqdnyCyvM1J2V1xxLXPUeRBmR2CXorYGF9Dye7NkgVdfA+9g9L/0Au6Ugn+2Cj5leoIgkgApN" + 596 "vuEcZegFlNOUPVEs3SlBgUF1BY6OBM0UBHTPwGGxFBBcetcuMRbUnu65vyDG0pslT59qpaR0TMVs" + 597 "P+tcheEzhyjbfM32/vwhnL9dBEgM8qMt0sqF6itNOQU/F4WGkK2Cm2v4CYEyKYw325fEhzTXosck" + 598 "MhbqmcyLab8EPceWF3dweoUT76+jEZx8lV2dapR+CmczQI43tV9btsd1xiBbBHAKvymm9Ep9bPzM" + 599 "J0MQi+OtURL9Lxke/70/MRueqbPeUlOaGvANTmXQD2OnW7PISwJ9lpeLfTG0LcqkoqkbtLKQLYHI" + 600 "rQfV5j0j+wmvmpMxzjN3uvNajLa4zQ8l0Eok9SFaRr2RL0gN8Q2JegfOL4pUiHPsh64WWya2NB7f" + 601 "V+1s65eA5ospXYsShRjo046QhGTmymwXXzdzuxu8IlnTEont6P4+J+GsWk6cldGbl20hctuUKzyx" + 602 "OptjEPOKejV60iDCYGmHbCWAzQ8h5MILV82IclzNViZmzAapeeCnexhpXhWTs+xDEYSKEiG/camt" + 603 "bhmZc3BcyVJrW23PktSfpBQ6D8ZxoMfF0L7V2GQMaUg+3r7ucrx82kpqotjv0xHghNIm95aBr1Qw" + 604 "1gaEjsC/0wGmmBDg1dTDH+F1p9TInzr3EFuYD0YiQ7YlAHq3cPuyGoLXJ5dXYuSBfhDXJSeddUkl" + 605 "k1ufZyOOcskeInQge7jzaRfmKg3U94r+spMEvb0AzDQVOKvjjo1ivxMSgFRZaDb/4qw="; 606 607 /** 608 * Defines the keystore contents for the client, BKS version. Holds just a 609 * single self-generated key. The subject name is "Test Client". 610 */ 611 private static final String CLIENT_KEYS_BKS = 612 "AAAAAQAAABT4Rka6fxbFps98Y5k2VilmbibNkQAABfQEAAVteWtleQAAARpYl+POAAAAAQAFWC41" + 613 "MDkAAAJNMIICSTCCAbKgAwIBAgIESEfU9TANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJVUzET" + 614 "MBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNV" + 615 "BAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgQ2xpZW50MB4XDTA4MDYwNTExNTg0NVoXDTA4MDkw" + 616 "MzExNTg0NVowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01U" + 617 "VjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRQwEgYDVQQDEwtUZXN0IENsaWVu" + 618 "dDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEApUvmWsQDHPpbDKK13Yez2/q54tTOmRml/qva" + 619 "2K6dZjkjSTW0iRuk7ztaVEvdJpfVIDv1oBsCI51ttyLHROy1epjF+GoL74mJb7fkcd0VOoSOTjtD" + 620 "+3GgZkHPAm5YmUYxiJXqxKKJJqMCTIW46eJaA2nAep9QIwZ14/NFAs4ObV8CAwEAATANBgkqhkiG" + 621 "9w0BAQUFAAOBgQCJrCr3hZQFDlLIfsSKI1/w+BLvyf4fubOid0pBxfklR8KBNPTiqjSmu7pd/C/F" + 622 "1FR8CdZUDoPflZHCOU+fj5r5KUC1HyigY/tEUvlforBpfB0uCF+tXW4DbUfOWhfMtLV4nCOJOOZg" + 623 "awfZLJWBJouLKOp427vDftxTSB+Ks8YjlgAAAqwAAAAU+NH6TtrzjyDdCXm5B6Vo7xX5G4YAAAZx" + 624 "EAUkcZtmykn7YdaYxC1jRFJ+GEJpC8nZVg83QClVuCSIS8a5f8Hl44Bk4oepOZsPzhtz3RdVzDVi" + 625 "RFfoyZFsrk9F5bDTVJ6sQbb/1nfJkLhZFXokka0vND5AXMSoD5Bj1Fqem3cK7fSUyqKvFoRKC3XD" + 626 "FQvhqoam29F1rbl8FaYdPvhhZo8TfZQYUyUKwW+RbR44M5iHPx+ykieMe/C/4bcM3z8cwIbYI1aO" + 627 "gjQKS2MK9bs17xaDzeAh4sBKrskFGrDe+2dgvrSKdoakJhLTNTBSG6m+rzqMSCeQpafLKMSjTSSz" + 628 "+KoQ9bLyax8cbvViGGju0SlVhquloZmKOfHr8TukIoV64h3uCGFOVFtQjCYDOq6NbfRvMh14UVF5" + 629 "zgDIGczoD9dMoULWxBmniGSntoNgZM+QP6Id7DBasZGKfrHIAw3lHBqcvB5smemSu7F4itRoa3D8" + 630 "N7hhUEKAc+xA+8NKmXfiCBoHfPHTwDvt4IR7gWjeP3Xv5vitcKQ/MAfO5RwfzkYCXQ3FfjfzmsE1" + 631 "1IfLRDiBj+lhQSulhRVStKI88Che3M4JUNGKllrc0nt1pWa1vgzmUhhC4LSdm6trTHgyJnB6OcS9" + 632 "t2furYjK88j1AuB4921oxMxRm8c4Crq8Pyuf+n3YKi8Pl2BzBtw++0gj0ODlgwut8SrVj66/nvIB" + 633 "jN3kLVahR8nZrEFF6vTTmyXi761pzq9yOVqI57wJGx8o3Ygox1p+pWUPl1hQR7rrhUbgK/Q5wno9" + 634 "uJk07h3IZnNxE+/IKgeMTP/H4+jmyT4mhsexJ2BFHeiKF1KT/FMcJdSi+ZK5yoNVcYuY8aZbx0Ef" + 635 "lHorCXAmLFB0W6Cz4KPP01nD9YBB4olxiK1t7m0AU9zscdivNiuUaB5OIEr+JuZ6dNw="; 636 637 String cipherSuiteJKS = "SSL_RSA_WITH_RC4_128_MD5"; 638 /** 639 * Defines the keystore contents for the server, JKS version. Holds just a 640 * single self-generated key. The subject name is "Test Server". 641 */ 642 private static final String SERVER_KEYS_JKS = 643 "/u3+7QAAAAIAAAABAAAAAQAFbXlrZXkAAAEaWFfBeAAAArowggK2MA4GCisGAQQBKgIRAQEFAASC" + 644 "AqI2kp5XjnF8YZkhcF92YsJNQkvsmH7zqMM87j23zSoV4DwyE3XeC/gZWq1ToScIhoqZkzlbWcu4" + 645 "T/Zfc/DrfGk/rKbBL1uWKGZ8fMtlZk8KoAhxZk1JSyJvdkyKxqmzUbxk1OFMlN2VJNu97FPVH+du" + 646 "dvjTvmpdoM81INWBW/1fZJeQeDvn4mMbbe0IxgpiLnI9WSevlaDP/sm1X3iO9yEyzHLL+M5Erspo" + 647 "Cwa558fOu5DdsICMXhvDQxjWFKFhPHnKtGe+VvwkG9/bAaDgx3kfhk0w5zvdnkKb+8Ed9ylNRzdk" + 648 "ocAa/mxlMTOsTvDKXjjsBupNPIIj7OP4GNnZaxkJjSs98pEO67op1GX2qhy6FSOPNuq8k/65HzUc" + 649 "PYn6voEeh6vm02U/sjEnzRevQ2+2wXoAdp0EwtQ/DlMe+NvcwPGWKuMgX4A4L93DZGb04N2VmAU3" + 650 "YLOtZwTO0LbuWrcCM/q99G/7LcczkxIVrO2I/rh8RXVczlf9QzcrFObFv4ATuspWJ8xG7DhsMbnk" + 651 "rT94Pq6TogYeoz8o8ZMykesAqN6mt/9+ToIemmXv+e+KU1hI5oLwWMnUG6dXM6hIvrULY6o+QCPH" + 652 "172YQJMa+68HAeS+itBTAF4Clm/bLn6reHCGGU6vNdwU0lYldpiOj9cB3t+u2UuLo6tiFWjLf5Zs" + 653 "EQJETd4g/EK9nHxJn0GAKrWnTw7pEHQJ08elzUuy04C/jEEG+4QXU1InzS4o/kR0Sqz2WTGDoSoq" + 654 "ewuPRU5bzQs/b9daq3mXrnPtRBL6HfSDAdpTK76iHqLCGdqx3avHjVSBm4zFvEuYBCev+3iKOBmg" + 655 "yh7eQRTjz4UOWfy85omMBr7lK8PtfVBDzOXpasxS0uBgdUyBDX4tO6k9jZ8a1kmQRQAAAAEABVgu" + 656 "NTA5AAACSDCCAkQwggGtAgRIR8SKMA0GCSqGSIb3DQEBBAUAMGkxCzAJBgNVBAYTAlVTMRMwEQYD" + 657 "VQQIEwpDYWxpZm9ybmlhMQwwCgYDVQQHEwNNVFYxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMH" + 658 "QW5kcm9pZDEUMBIGA1UEAxMLVGVzdCBTZXJ2ZXIwHhcNMDgwNjA1MTA0ODQyWhcNMDgwOTAzMTA0" + 659 "ODQyWjBpMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8w" + 660 "DQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMIGf" + 661 "MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwoC6chqCI84rj1PrXuJgbiit4EV909zR6N0jNlYfg" + 662 "itwB39bP39wH03rFm8T59b3mbSptnGmCIpLZn25KPPFsYD3JJ+wFlmiUdEP9H05flfwtFQJnw9uT" + 663 "3rRIdYVMPcQ3RoZzwAMliGr882I2thIDbA6xjGU/1nRIdvk0LtxH3QIDAQABMA0GCSqGSIb3DQEB" + 664 "BAUAA4GBAJn+6YgUlY18Ie+0+Vt8oEi81DNi/bfPrAUAh63fhhBikx/3R9dl3wh09Z6p7cIdNxjW" + 665 "n2ll+cRW9eqF7z75F0Omm0C7/KAEPjukVbszmzeU5VqzkpSt0j84YWi+TfcHRrfvhLbrlmGITVpY" + 666 "ol5pHLDyqGmDs53pgwipWqsn/nEXEBgj3EoqPeqHbDf7YaP8h/5BSt0="; 667 668 /** 669 * Defines the keystore contents for the client, JKS version. Holds just a 670 * single self-generated key. The subject name is "Test Client". 671 */ 672 private static final String CLIENT_KEYS_JKS = 673 "/u3+7QAAAAIAAAABAAAAAQAFbXlrZXkAAAEaWFhyMAAAArkwggK1MA4GCisGAQQBKgIRAQEFAASC" + 674 "AqGVSfXolBStZy4nnRNn4fAr+S7kfU2BS23wwW8uB2Ru3GvtLzlK9q08Gvq/LNqBafjyFTVL5FV5" + 675 "SED/8YomO5a98GpskSeRvytCiTBLJdgGhws5TOGekgIAcBROPGIyOtJPQ0HfOQs+BqgzGDHzHQhw" + 676 "u/8Tm6yQwiP+W/1I9B1QnaEztZA3mhTyMMJsmsFTYroGgAog885D5Cmzd8sYGfxec3R6I+xcmBAY" + 677 "eibR5kGpWwt1R+qMvRrtBqh5r6WSKhCBNax+SJVbtUNRiKyjKccdJg6fGqIWWeivwYTy0OhjA6b4" + 678 "NiZ/ZZs5pxFGWUj/Rlp0RYy8fCF6aw5/5s4Bf4MI6dPSqMG8Hf7sJR91GbcELyzPdM0h5lNavgit" + 679 "QPEzKeuDrGxhY1frJThBsNsS0gxeu+OgfJPEb/H4lpYX5IvuIGbWKcxoO9zq4/fimIZkdA8A+3eY" + 680 "mfDaowvy65NBVQPJSxaOyFhLHfeLqOeCsVENAea02vA7andZHTZehvcrqyKtm+z8ncHGRC2H9H8O" + 681 "jKwKHfxxrYY/jMAKLl00+PBb3kspO+BHI2EcQnQuMw/zr83OR9Meq4TJ0TMuNkApZELAeFckIBbS" + 682 "rBr8NNjAIfjuCTuKHhsTFWiHfk9ZIzigxXagfeDRiyVc6khOuF/bGorj23N2o7Rf3uLoU6PyXWi4" + 683 "uhctR1aL6NzxDoK2PbYCeA9hxbDv8emaVPIzlVwpPK3Ruvv9mkjcOhZ74J8bPK2fQmbplbOljcZi" + 684 "tZijOfzcO/11JrwhuJZRA6wanTqHoujgChV9EukVrmbWGGAcewFnAsSbFXIik7/+QznXaDIt5NgL" + 685 "H/Bcz4Z/fdV7Ae1eUaxKXdPbI//4J+8liVT/d8awjW2tldIaDlmGMR3aoc830+3mAAAAAQAFWC41" + 686 "MDkAAAJIMIICRDCCAa0CBEhHxLgwDQYJKoZIhvcNAQEEBQAwaTELMAkGA1UEBhMCVVMxEzARBgNV" + 687 "BAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01UVjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdB" + 688 "bmRyb2lkMRQwEgYDVQQDEwtUZXN0IENsaWVudDAeFw0wODA2MDUxMDQ5MjhaFw0wODA5MDMxMDQ5" + 689 "MjhaMGkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMQwwCgYDVQQHEwNNVFYxDzAN" + 690 "BgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHQW5kcm9pZDEUMBIGA1UEAxMLVGVzdCBDbGllbnQwgZ8w" + 691 "DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIK3Q+KiFbmCGg422TAo4gggdhMH6FJhiuz8DxRyeMKR" + 692 "UAfP4MK0wtc8N42waZ6OKvxpBFUy0BRfBsX0GD4Ku99yu9/tavSigTraeJtwV3WWRRjIqk7L3wX5" + 693 "cmgS2KSD43Y0rNUKrko26lnt9N4qiYRBSj+tcAN3Lx9+ptqk1LApAgMBAAEwDQYJKoZIhvcNAQEE" + 694 "BQADgYEANb7Q1GVSuy1RPJ0FmiXoMYCCtvlRLkmJphwxovK0cAQK12Vll+yAzBhHiQHy/RA11mng" + 695 "wYudC7u3P8X/tBT8GR1Yk7QW3KgFyPafp3lQBBCraSsfrjKj+dCLig1uBLUr4f68W8VFWZWWTHqp" + 696 "NMGpCX6qmjbkJQLVK/Yfo1ePaUexPSOX0G9m8+DoV3iyNw6at01NRw=="; 697 698 699 int port; 700 SSLSocket serverSocket; 701 MyHandshakeListener listener; 702 String host = "localhost"; 703 boolean notFinished = true; 704 SSLSession clientSession = null; 705 SSLContext clientSslContext = null; 706 String testData = "PING"; 707 708 private String PASSWORD = "android"; 709 710 String cipherSuite = (useBKS ? cipherSuiteBKS : cipherSuiteJKS); 711 712 /** 713 * Implements a test SSL socket server. It waits for a connection on a given 714 * port, requests client authentication (if specified), reads from the socket, 715 * and writes to the socket. 716 */ 717 class TestServer implements Runnable { 718 719 public static final int CLIENT_AUTH_NONE = 0; 720 721 public static final int CLIENT_AUTH_WANTED = 1; 722 723 public static final int CLIENT_AUTH_NEEDED = 2; 724 725 private TestTrustManager trustManager; 726 727 private Exception exception; 728 729 String keys; 730 731 private int clientAuth; 732 733 private boolean provideKeys; 734 735 private KeyStore store; 736 737 public TestServer(boolean provideKeys, int clientAuth, String keys) { 738 this.keys = keys; 739 this.clientAuth = clientAuth; 740 this.provideKeys = provideKeys; 741 742 trustManager = new TestTrustManager(); 743 } 744 745 public void run() { 746 try { 747 store = provideKeys ? getKeyStore(keys) : null; 748 KeyManager[] keyManagers = store != null ? getKeyManagers(store) : null; 749 TrustManager[] trustManagers = new TrustManager[] { trustManager }; 750 751 SSLContext sslContext = SSLContext.getInstance("TLS"); 752 sslContext.init(keyManagers, trustManagers, null); 753 754 SSLServerSocket serverSocket = (SSLServerSocket)sslContext 755 .getServerSocketFactory().createServerSocket(); 756 757 if (clientAuth == CLIENT_AUTH_WANTED) { 758 serverSocket.setWantClientAuth(true); 759 } else if (clientAuth == CLIENT_AUTH_NEEDED) { 760 serverSocket.setNeedClientAuth(true); 761 } else { 762 serverSocket.setWantClientAuth(false); 763 } 764 765 serverSocket.bind(new InetSocketAddress(port)); 766 767 SSLSocket clientSocket = (SSLSocket)serverSocket.accept(); 768 769 InputStream istream = clientSocket.getInputStream(); 770 byte[] buffer = new byte[1024]; 771 istream.read(buffer); 772 773 OutputStream ostream = clientSocket.getOutputStream(); 774 ostream.write(testData.getBytes()); 775 ostream.flush(); 776 777 while (notFinished) { 778 Thread.currentThread().sleep(500); 779 } 780 781 clientSocket.close(); 782 serverSocket.close(); 783 784 } catch (Exception ex) { 785 exception = ex; 786 } 787 } 788 789 public Exception getException() { 790 return exception; 791 } 792 793 public X509Certificate[] getChain() { 794 return trustManager.getChain(); 795 } 796 797 public KeyStore getStore() { 798 return store; 799 } 800 801 } 802 803 /** 804 * Implements a test SSL socket client. It opens a connection to localhost on 805 * a given port, writes to the socket, and reads from the socket. 806 */ 807 class TestClient implements Runnable { 808 809 private TestTrustManager trustManager; 810 811 private Exception exception; 812 813 private String keys; 814 815 private boolean provideKeys; 816 817 private KeyStore store; 818 819 public TestClient(boolean provideKeys, String keys) { 820 this.keys = keys; 821 this.provideKeys = provideKeys; 822 823 trustManager = new TestTrustManager(); 824 } 825 826 public void run() { 827 try { 828 store = provideKeys ? getKeyStore(keys) : null; 829 KeyManager[] keyManagers = store != null ? getKeyManagers(store) : null; 830 TrustManager[] trustManagers = new TrustManager[] { trustManager }; 831 832 clientSslContext = SSLContext.getInstance("TLS"); 833 clientSslContext.init(keyManagers, trustManagers, null); 834 835 SSLSocket socket = (SSLSocket)clientSslContext.getSocketFactory().createSocket(); 836 837 socket.connect(new InetSocketAddress(port)); 838 OutputStream ostream = socket.getOutputStream(); 839 ostream.write(testData.getBytes()); 840 ostream.flush(); 841 842 InputStream istream = socket.getInputStream(); 843 byte[] buffer = new byte[1024]; 844 istream.read(buffer); 845 846 clientSession = socket.getSession(); 847 while (notFinished) { 848 Thread.currentThread().sleep(500); 849 } 850 socket.close(); 851 852 } catch (Exception ex) { 853 exception = ex; 854 } 855 } 856 857 public Exception getException() { 858 return exception; 859 } 860 861 public X509Certificate[] getChain() { 862 return trustManager.getChain(); 863 } 864 865 public KeyStore getStore() { 866 return store; 867 } 868 } 869 870 /** 871 * Loads a keystore from a base64-encoded String. Returns the KeyManager[] 872 * for the result. 873 */ 874 private KeyStore getKeyStore(String keys) throws Exception { 875 byte[] bytes = new Base64().decode(keys.getBytes()); 876 InputStream inputStream = new ByteArrayInputStream(bytes); 877 878 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 879 keyStore.load(inputStream, PASSWORD.toCharArray()); 880 inputStream.close(); 881 return keyStore; 882 } 883 884 /** 885 * Loads a keystore from a base64-encoded String. Returns the KeyManager[] 886 * for the result. 887 */ 888 private KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception { 889 String algorithm = KeyManagerFactory.getDefaultAlgorithm(); 890 KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(algorithm); 891 keyManagerFactory.init(keyStore, PASSWORD.toCharArray()); 892 893 return keyManagerFactory.getKeyManagers(); 894 } 895} 896