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 18 package org.apache.harmony.tests.javax.net.ssl; 19 20 import java.io.ByteArrayInputStream; 21 import java.io.InputStream; 22 import java.io.OutputStream; 23 import java.net.InetSocketAddress; 24 import java.security.KeyStore; 25 import java.security.Principal; 26 import java.security.cert.Certificate; 27 import java.security.cert.X509Certificate; 28 import java.util.Arrays; 29 import java.util.Base64; 30 31 import javax.net.ssl.ExtendedSSLSession; 32 import javax.net.ssl.KeyManager; 33 import javax.net.ssl.KeyManagerFactory; 34 import javax.net.ssl.SSLContext; 35 import javax.net.ssl.SSLServerSocket; 36 import javax.net.ssl.SSLSession; 37 import javax.net.ssl.SSLSessionBindingEvent; 38 import javax.net.ssl.SSLSessionBindingListener; 39 import javax.net.ssl.SSLSocket; 40 import javax.net.ssl.TrustManager; 41 42 import org.apache.harmony.tests.javax.net.ssl.HandshakeCompletedEventTest.MyHandshakeListener; 43 import org.apache.harmony.tests.javax.net.ssl.HandshakeCompletedEventTest.TestTrustManager; 44 45 import junit.framework.TestCase; 46 import libcore.java.security.StandardNames; 47 48 public class SSLSessionTest extends TestCase { 49 50 // set to true if on Android, false if on RI 51 boolean useBKS = true; 52 53 /** 54 * javax.net.ssl.SSLSession#getPeerHost() 55 * javax.net.ssl.SSLSession#getPeerPort() 56 */ test_getPeerHost()57 public void test_getPeerHost() throws Exception { 58 SSLSession s = clientSession; 59 assertEquals(((InetSocketAddress) serverSocket.getLocalSocketAddress()).getHostString(), 60 s.getPeerHost()); 61 assertEquals(serverSocket.getLocalPort(), s.getPeerPort()); 62 } 63 64 /** 65 * javax.net.ssl.SSLSession#invalidate() 66 * javax.net.ssl.SSLSession#isValid() 67 */ test_invalidate()68 public void test_invalidate() { 69 SSLSession s = clientSession; 70 assertTrue(s.isValid()); 71 s.invalidate(); 72 assertFalse(s.isValid()); 73 } 74 75 /** 76 * javax.net.ssl.SSLSession#getPeerPrincipal() 77 */ test_getPeerPrincipal()78 public void test_getPeerPrincipal() throws Exception { 79 Principal p1 = clientSession.getPeerPrincipal(); 80 KeyStore store = server.getStore(); 81 X509Certificate cert = (X509Certificate)store.getCertificate("mykey"); 82 Principal p2 = cert.getSubjectX500Principal(); 83 assertEquals(p1, p2); 84 } 85 86 /** 87 * javax.net.ssl.SSLSession#getApplicationBufferSize() 88 */ test_getApplicationBufferSize()89 public void test_getApplicationBufferSize() { 90 assertTrue(clientSession.getApplicationBufferSize() > 0); 91 } 92 93 /** 94 * javax.net.ssl.SSLSession#getCreationTime() 95 */ test_getCreationTime()96 public void test_getCreationTime() { 97 // check if creation time was in the last 10 seconds 98 long currentTime = System.currentTimeMillis(); 99 long sessionTime = clientSession.getCreationTime(); 100 long diff = currentTime - sessionTime; 101 assertTrue("diff between " + currentTime + " and " + sessionTime + " should be < 10000", 102 diff < 10000); 103 } 104 105 /** 106 * javax.net.ssl.SSLSession#getLastAccessedTime() 107 */ test_getLastAccessedTime()108 public void test_getLastAccessedTime() { 109 // check if last access time was in the last 10 seconds 110 long currentTime = System.currentTimeMillis(); 111 long sessionTime = clientSession.getLastAccessedTime(); 112 long diff = currentTime - sessionTime; 113 assertTrue("diff between " + currentTime + " and " + sessionTime + " should be < 10000", 114 diff < 10000); 115 assertTrue ("diff should be < 10000 but is " + diff, diff < 10000); 116 } 117 118 /** 119 * javax.net.ssl.SSLSession#getLocalCertificates() 120 */ test_getLocalCertificates()121 public void test_getLocalCertificates() throws Exception { 122 KeyStore store = client.getStore(); 123 Certificate cert = store.getCertificate("mykey"); 124 Certificate[] certs = clientSession.getLocalCertificates(); 125 assertEquals(cert, certs[0]); 126 } 127 128 /** 129 * javax.net.ssl.SSLSession#getLocalPrincipal() 130 */ test_getLocalPrincipal()131 public void test_getLocalPrincipal() throws Exception { 132 Principal p1 = clientSession.getLocalPrincipal(); 133 KeyStore store = client.getStore(); 134 X509Certificate cert = (X509Certificate)store.getCertificate("mykey"); 135 Principal p2 = cert.getSubjectX500Principal(); 136 assertEquals(p1, p2); 137 } 138 139 /** 140 * javax.net.ssl.SSLSession#getPacketBufferSize() 141 */ test_getPacketBufferSize()142 public void test_getPacketBufferSize() { 143 assertTrue(clientSession.getPacketBufferSize() > 0); 144 } 145 146 /** 147 * javax.net.ssl.SSLSession#getPeerCertificates() 148 */ test_getPeerCertificates()149 public void test_getPeerCertificates() throws Exception { 150 Certificate[] res = clientSession.getPeerCertificates(); 151 assertTrue(res.length > 0); 152 } 153 154 /** 155 * javax.net.ssl.SSLSession#getPeerCertificateChain() 156 */ test_getPeerCertificateChain()157 public void test_getPeerCertificateChain() throws Exception { 158 javax.security.cert.X509Certificate[] res = clientSession.getPeerCertificateChain(); 159 assertTrue(res.length > 0); 160 } 161 162 /** 163 * javax.net.ssl.SSLSession#getProtocol() 164 */ test_getProtocol()165 public void test_getProtocol() { 166 assertEquals("TLSv1.3", clientSession.getProtocol()); 167 } 168 169 /** 170 * javax.net.ssl.SSLSession#getSessionContext() 171 */ test_getSessionContext()172 public void test_getSessionContext() { 173 assertEquals(clientSession.getSessionContext(), 174 clientSslContext.getClientSessionContext()); 175 } 176 177 /** 178 * javax.net.ssl.SSLSession#putValue(String name, Object value) 179 * javax.net.ssl.SSLSession#removeValue(String name) 180 * javax.net.ssl.SSLSession#getValueNames() 181 */ test_putValue()182 public void test_putValue() { 183 SSLSession s = clientSession; 184 mySSLSessionBindingListener sbl = new mySSLSessionBindingListener(); 185 assertNotNull(s.getValueNames()); 186 assertEquals(0, s.getValueNames().length); 187 s.putValue("Name_01", sbl); 188 s.putValue("Name_02", sbl); 189 s.putValue("Name_03", sbl); 190 assertEquals(3, s.getValueNames().length); 191 s.removeValue("Name_01"); 192 assertEquals(2, s.getValueNames().length); 193 194 try { 195 s.putValue(null, null); 196 fail("Exception wasn't thrown"); 197 } catch (IllegalArgumentException | NullPointerException expected) { 198 // expected 199 } 200 try { 201 s.putValue("ABC", null); 202 fail("Exception wasn't thrown"); 203 } catch (IllegalArgumentException | NullPointerException expected) { 204 // expected 205 } 206 try { 207 s.putValue(null, sbl); 208 fail("Exception wasn't thrown"); 209 } catch (IllegalArgumentException | NullPointerException expected) { 210 // expected 211 } 212 213 try { 214 s.removeValue(null); 215 fail("Exception wasn't thrown"); 216 } catch (IllegalArgumentException | NullPointerException expected) { 217 // expected 218 } 219 } 220 221 /** 222 * javax.net.ssl.SSLSession#getValue(String name) 223 */ test_getValue()224 public void test_getValue() { 225 SSLSession s = clientSession; 226 mySSLSessionBindingListener sbl = new mySSLSessionBindingListener(); 227 228 try { 229 s.getValue(null); 230 fail("Exception wasn't thrown"); 231 } catch (IllegalArgumentException | NullPointerException expected) { 232 // expected 233 } 234 235 s.putValue("Name", sbl); 236 Object obj = s.getValue("Name"); 237 assertTrue(obj instanceof SSLSessionBindingListener); 238 } 239 240 Thread serverThread, clientThread; 241 TestServer server; 242 TestClient client; 243 244 @Override setUp()245 protected void setUp() throws Exception { 246 String serverKeys = (useBKS ? SERVER_KEYS_BKS : SERVER_KEYS_JKS); 247 String clientKeys = (useBKS ? CLIENT_KEYS_BKS : CLIENT_KEYS_JKS); 248 server = new TestServer(true, TestServer.CLIENT_AUTH_WANTED, serverKeys); 249 client = new TestClient(true, clientKeys); 250 251 serverThread = new Thread(server); 252 clientThread = new Thread(client); 253 254 serverThread.start(); 255 try { 256 Thread.currentThread().sleep(1000); 257 clientThread.start(); 258 } catch (InterruptedException e) { 259 fail("Could not create server or cient " + e.getMessage()); 260 } 261 while (clientSession == null 262 && server.exception == null 263 && client.exception == null) { 264 try { 265 Thread.currentThread().sleep(500); 266 } catch (InterruptedException e) { 267 fail("couldn't create session"); 268 } 269 } 270 if (server.exception != null) { 271 server.exception.printStackTrace(); 272 } 273 assertNull("server thread has a pending exception: " + server.exception, 274 server.exception); 275 if (client.exception != null) { 276 client.exception.printStackTrace(); 277 } 278 assertNull("client thread has a pending exception: " + client.exception, 279 client.exception); 280 assertNotNull("Could not initialize session", clientSession); 281 } 282 283 @Override tearDown()284 protected void tearDown() { 285 notFinished = false; 286 try { 287 serverThread.join(); 288 } catch (InterruptedException e) { 289 throw new RuntimeException(e); 290 } 291 try { 292 clientThread.join(); 293 } catch (InterruptedException e) { 294 throw new RuntimeException(e); 295 } 296 297 // The server must have completed without an exception. 298 if (server.getException() != null) { 299 throw new RuntimeException(server.getException()); 300 } 301 302 // The client must have completed without an exception. 303 if (client.getException() != null) { 304 throw new RuntimeException(client.getException()); 305 } 306 } 307 308 public class mySSLSessionBindingListener implements 309 SSLSessionBindingListener { mySSLSessionBindingListener()310 mySSLSessionBindingListener() { 311 } valueBound(SSLSessionBindingEvent event)312 public void valueBound(SSLSessionBindingEvent event) {} valueUnbound(SSLSessionBindingEvent event)313 public void valueUnbound(SSLSessionBindingEvent event) {} 314 } 315 316 /** 317 * Defines the keystore contents for the server, BKS version. Holds just a 318 * single self-generated key. The subject name is "Test Server". 319 */ 320 private static final String SERVER_KEYS_BKS = 321 "AAAAAQAAABQDkebzoP1XwqyWKRCJEpn/t8dqIQAABDkEAAVteWtleQAAARpYl20nAAAAAQAFWC41" 322 + "MDkAAAJNMIICSTCCAbKgAwIBAgIESEfU1jANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJVUzET" 323 + "MBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNV" 324 + "BAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMB4XDTA4MDYwNTExNTgxNFoXDTA4MDkw" 325 + "MzExNTgxNFowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01U" 326 + "VjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRQwEgYDVQQDEwtUZXN0IFNlcnZl" 327 + "cjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0LIdKaIr9/vsTq8BZlA3R+NFWRaH4lGsTAQy" 328 + "DPMF9ZqEDOaL6DJuu0colSBBBQ85hQTPa9m9nyJoN3pEi1hgamqOvQIWcXBk+SOpUGRZZFXwniJV" 329 + "zDKU5nE9MYgn2B9AoiH3CSuMz6HRqgVaqtppIe1jhukMc/kHVJvlKRNy9XMCAwEAATANBgkqhkiG" 330 + "9w0BAQUFAAOBgQC7yBmJ9O/eWDGtSH9BH0R3dh2NdST3W9hNZ8hIa8U8klhNHbUCSSktZmZkvbPU" 331 + "hse5LI3dh6RyNDuqDrbYwcqzKbFJaq/jX9kCoeb3vgbQElMRX8D2ID1vRjxwlALFISrtaN4VpWzV" 332 + "yeoHPW4xldeZmoVtjn8zXNzQhLuBqX2MmAAAAqwAAAAUvkUScfw9yCSmALruURNmtBai7kQAAAZx" 333 + "4Jmijxs/l8EBaleaUru6EOPioWkUAEVWCxjM/TxbGHOi2VMsQWqRr/DZ3wsDmtQgw3QTrUK666sR" 334 + "MBnbqdnyCyvM1J2V1xxLXPUeRBmR2CXorYGF9Dye7NkgVdfA+9g9L/0Au6Ugn+2Cj5leoIgkgApN" 335 + "vuEcZegFlNOUPVEs3SlBgUF1BY6OBM0UBHTPwGGxFBBcetcuMRbUnu65vyDG0pslT59qpaR0TMVs" 336 + "P+tcheEzhyjbfM32/vwhnL9dBEgM8qMt0sqF6itNOQU/F4WGkK2Cm2v4CYEyKYw325fEhzTXosck" 337 + "MhbqmcyLab8EPceWF3dweoUT76+jEZx8lV2dapR+CmczQI43tV9btsd1xiBbBHAKvymm9Ep9bPzM" 338 + "J0MQi+OtURL9Lxke/70/MRueqbPeUlOaGvANTmXQD2OnW7PISwJ9lpeLfTG0LcqkoqkbtLKQLYHI" 339 + "rQfV5j0j+wmvmpMxzjN3uvNajLa4zQ8l0Eok9SFaRr2RL0gN8Q2JegfOL4pUiHPsh64WWya2NB7f" 340 + "V+1s65eA5ospXYsShRjo046QhGTmymwXXzdzuxu8IlnTEont6P4+J+GsWk6cldGbl20hctuUKzyx" 341 + "OptjEPOKejV60iDCYGmHbCWAzQ8h5MILV82IclzNViZmzAapeeCnexhpXhWTs+xDEYSKEiG/camt" 342 + "bhmZc3BcyVJrW23PktSfpBQ6D8ZxoMfF0L7V2GQMaUg+3r7ucrx82kpqotjv0xHghNIm95aBr1Qw" 343 + "1gaEjsC/0wGmmBDg1dTDH+F1p9TInzr3EFuYD0YiQ7YlAHq3cPuyGoLXJ5dXYuSBfhDXJSeddUkl" 344 + "k1ufZyOOcskeInQge7jzaRfmKg3U94r+spMEvb0AzDQVOKvjjo1ivxMSgFRZaDb/4qw="; 345 346 /** 347 * Defines the keystore contents for the client, BKS version. Holds just a 348 * single self-generated key. The subject name is "Test Client". 349 */ 350 private static final String CLIENT_KEYS_BKS = 351 "AAAAAQAAABT4Rka6fxbFps98Y5k2VilmbibNkQAABfQEAAVteWtleQAAARpYl+POAAAAAQAFWC41" 352 + "MDkAAAJNMIICSTCCAbKgAwIBAgIESEfU9TANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJVUzET" 353 + "MBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNV" 354 + "BAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgQ2xpZW50MB4XDTA4MDYwNTExNTg0NVoXDTA4MDkw" 355 + "MzExNTg0NVowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01U" 356 + "VjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRQwEgYDVQQDEwtUZXN0IENsaWVu" 357 + "dDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEApUvmWsQDHPpbDKK13Yez2/q54tTOmRml/qva" 358 + "2K6dZjkjSTW0iRuk7ztaVEvdJpfVIDv1oBsCI51ttyLHROy1epjF+GoL74mJb7fkcd0VOoSOTjtD" 359 + "+3GgZkHPAm5YmUYxiJXqxKKJJqMCTIW46eJaA2nAep9QIwZ14/NFAs4ObV8CAwEAATANBgkqhkiG" 360 + "9w0BAQUFAAOBgQCJrCr3hZQFDlLIfsSKI1/w+BLvyf4fubOid0pBxfklR8KBNPTiqjSmu7pd/C/F" 361 + "1FR8CdZUDoPflZHCOU+fj5r5KUC1HyigY/tEUvlforBpfB0uCF+tXW4DbUfOWhfMtLV4nCOJOOZg" 362 + "awfZLJWBJouLKOp427vDftxTSB+Ks8YjlgAAAqwAAAAU+NH6TtrzjyDdCXm5B6Vo7xX5G4YAAAZx" 363 + "EAUkcZtmykn7YdaYxC1jRFJ+GEJpC8nZVg83QClVuCSIS8a5f8Hl44Bk4oepOZsPzhtz3RdVzDVi" 364 + "RFfoyZFsrk9F5bDTVJ6sQbb/1nfJkLhZFXokka0vND5AXMSoD5Bj1Fqem3cK7fSUyqKvFoRKC3XD" 365 + "FQvhqoam29F1rbl8FaYdPvhhZo8TfZQYUyUKwW+RbR44M5iHPx+ykieMe/C/4bcM3z8cwIbYI1aO" 366 + "gjQKS2MK9bs17xaDzeAh4sBKrskFGrDe+2dgvrSKdoakJhLTNTBSG6m+rzqMSCeQpafLKMSjTSSz" 367 + "+KoQ9bLyax8cbvViGGju0SlVhquloZmKOfHr8TukIoV64h3uCGFOVFtQjCYDOq6NbfRvMh14UVF5" 368 + "zgDIGczoD9dMoULWxBmniGSntoNgZM+QP6Id7DBasZGKfrHIAw3lHBqcvB5smemSu7F4itRoa3D8" 369 + "N7hhUEKAc+xA+8NKmXfiCBoHfPHTwDvt4IR7gWjeP3Xv5vitcKQ/MAfO5RwfzkYCXQ3FfjfzmsE1" 370 + "1IfLRDiBj+lhQSulhRVStKI88Che3M4JUNGKllrc0nt1pWa1vgzmUhhC4LSdm6trTHgyJnB6OcS9" 371 + "t2furYjK88j1AuB4921oxMxRm8c4Crq8Pyuf+n3YKi8Pl2BzBtw++0gj0ODlgwut8SrVj66/nvIB" 372 + "jN3kLVahR8nZrEFF6vTTmyXi761pzq9yOVqI57wJGx8o3Ygox1p+pWUPl1hQR7rrhUbgK/Q5wno9" 373 + "uJk07h3IZnNxE+/IKgeMTP/H4+jmyT4mhsexJ2BFHeiKF1KT/FMcJdSi+ZK5yoNVcYuY8aZbx0Ef" 374 + "lHorCXAmLFB0W6Cz4KPP01nD9YBB4olxiK1t7m0AU9zscdivNiuUaB5OIEr+JuZ6dNw="; 375 376 /** 377 * Defines the keystore contents for the server, JKS version. Holds just a 378 * single self-generated key. The subject name is "Test Server". 379 */ 380 private static final String SERVER_KEYS_JKS = 381 "/u3+7QAAAAIAAAABAAAAAQAFbXlrZXkAAAEaWFfBeAAAArowggK2MA4GCisGAQQBKgIRAQEFAASC" 382 + "AqI2kp5XjnF8YZkhcF92YsJNQkvsmH7zqMM87j23zSoV4DwyE3XeC/gZWq1ToScIhoqZkzlbWcu4" 383 + "T/Zfc/DrfGk/rKbBL1uWKGZ8fMtlZk8KoAhxZk1JSyJvdkyKxqmzUbxk1OFMlN2VJNu97FPVH+du" 384 + "dvjTvmpdoM81INWBW/1fZJeQeDvn4mMbbe0IxgpiLnI9WSevlaDP/sm1X3iO9yEyzHLL+M5Erspo" 385 + "Cwa558fOu5DdsICMXhvDQxjWFKFhPHnKtGe+VvwkG9/bAaDgx3kfhk0w5zvdnkKb+8Ed9ylNRzdk" 386 + "ocAa/mxlMTOsTvDKXjjsBupNPIIj7OP4GNnZaxkJjSs98pEO67op1GX2qhy6FSOPNuq8k/65HzUc" 387 + "PYn6voEeh6vm02U/sjEnzRevQ2+2wXoAdp0EwtQ/DlMe+NvcwPGWKuMgX4A4L93DZGb04N2VmAU3" 388 + "YLOtZwTO0LbuWrcCM/q99G/7LcczkxIVrO2I/rh8RXVczlf9QzcrFObFv4ATuspWJ8xG7DhsMbnk" 389 + "rT94Pq6TogYeoz8o8ZMykesAqN6mt/9+ToIemmXv+e+KU1hI5oLwWMnUG6dXM6hIvrULY6o+QCPH" 390 + "172YQJMa+68HAeS+itBTAF4Clm/bLn6reHCGGU6vNdwU0lYldpiOj9cB3t+u2UuLo6tiFWjLf5Zs" 391 + "EQJETd4g/EK9nHxJn0GAKrWnTw7pEHQJ08elzUuy04C/jEEG+4QXU1InzS4o/kR0Sqz2WTGDoSoq" 392 + "ewuPRU5bzQs/b9daq3mXrnPtRBL6HfSDAdpTK76iHqLCGdqx3avHjVSBm4zFvEuYBCev+3iKOBmg" 393 + "yh7eQRTjz4UOWfy85omMBr7lK8PtfVBDzOXpasxS0uBgdUyBDX4tO6k9jZ8a1kmQRQAAAAEABVgu" 394 + "NTA5AAACSDCCAkQwggGtAgRIR8SKMA0GCSqGSIb3DQEBBAUAMGkxCzAJBgNVBAYTAlVTMRMwEQYD" 395 + "VQQIEwpDYWxpZm9ybmlhMQwwCgYDVQQHEwNNVFYxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMH" 396 + "QW5kcm9pZDEUMBIGA1UEAxMLVGVzdCBTZXJ2ZXIwHhcNMDgwNjA1MTA0ODQyWhcNMDgwOTAzMTA0" 397 + "ODQyWjBpMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8w" 398 + "DQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMIGf" 399 + "MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwoC6chqCI84rj1PrXuJgbiit4EV909zR6N0jNlYfg" 400 + "itwB39bP39wH03rFm8T59b3mbSptnGmCIpLZn25KPPFsYD3JJ+wFlmiUdEP9H05flfwtFQJnw9uT" 401 + "3rRIdYVMPcQ3RoZzwAMliGr882I2thIDbA6xjGU/1nRIdvk0LtxH3QIDAQABMA0GCSqGSIb3DQEB" 402 + "BAUAA4GBAJn+6YgUlY18Ie+0+Vt8oEi81DNi/bfPrAUAh63fhhBikx/3R9dl3wh09Z6p7cIdNxjW" 403 + "n2ll+cRW9eqF7z75F0Omm0C7/KAEPjukVbszmzeU5VqzkpSt0j84YWi+TfcHRrfvhLbrlmGITVpY" 404 + "ol5pHLDyqGmDs53pgwipWqsn/nEXEBgj3EoqPeqHbDf7YaP8h/5BSt0="; 405 406 /** 407 * Defines the keystore contents for the client, JKS version. Holds just a 408 * single self-generated key. The subject name is "Test Client". 409 */ 410 private static final String CLIENT_KEYS_JKS = 411 "/u3+7QAAAAIAAAABAAAAAQAFbXlrZXkAAAEaWFhyMAAAArkwggK1MA4GCisGAQQBKgIRAQEFAASC" 412 + "AqGVSfXolBStZy4nnRNn4fAr+S7kfU2BS23wwW8uB2Ru3GvtLzlK9q08Gvq/LNqBafjyFTVL5FV5" 413 + "SED/8YomO5a98GpskSeRvytCiTBLJdgGhws5TOGekgIAcBROPGIyOtJPQ0HfOQs+BqgzGDHzHQhw" 414 + "u/8Tm6yQwiP+W/1I9B1QnaEztZA3mhTyMMJsmsFTYroGgAog885D5Cmzd8sYGfxec3R6I+xcmBAY" 415 + "eibR5kGpWwt1R+qMvRrtBqh5r6WSKhCBNax+SJVbtUNRiKyjKccdJg6fGqIWWeivwYTy0OhjA6b4" 416 + "NiZ/ZZs5pxFGWUj/Rlp0RYy8fCF6aw5/5s4Bf4MI6dPSqMG8Hf7sJR91GbcELyzPdM0h5lNavgit" 417 + "QPEzKeuDrGxhY1frJThBsNsS0gxeu+OgfJPEb/H4lpYX5IvuIGbWKcxoO9zq4/fimIZkdA8A+3eY" 418 + "mfDaowvy65NBVQPJSxaOyFhLHfeLqOeCsVENAea02vA7andZHTZehvcrqyKtm+z8ncHGRC2H9H8O" 419 + "jKwKHfxxrYY/jMAKLl00+PBb3kspO+BHI2EcQnQuMw/zr83OR9Meq4TJ0TMuNkApZELAeFckIBbS" 420 + "rBr8NNjAIfjuCTuKHhsTFWiHfk9ZIzigxXagfeDRiyVc6khOuF/bGorj23N2o7Rf3uLoU6PyXWi4" 421 + "uhctR1aL6NzxDoK2PbYCeA9hxbDv8emaVPIzlVwpPK3Ruvv9mkjcOhZ74J8bPK2fQmbplbOljcZi" 422 + "tZijOfzcO/11JrwhuJZRA6wanTqHoujgChV9EukVrmbWGGAcewFnAsSbFXIik7/+QznXaDIt5NgL" 423 + "H/Bcz4Z/fdV7Ae1eUaxKXdPbI//4J+8liVT/d8awjW2tldIaDlmGMR3aoc830+3mAAAAAQAFWC41" 424 + "MDkAAAJIMIICRDCCAa0CBEhHxLgwDQYJKoZIhvcNAQEEBQAwaTELMAkGA1UEBhMCVVMxEzARBgNV" 425 + "BAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01UVjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdB" 426 + "bmRyb2lkMRQwEgYDVQQDEwtUZXN0IENsaWVudDAeFw0wODA2MDUxMDQ5MjhaFw0wODA5MDMxMDQ5" 427 + "MjhaMGkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMQwwCgYDVQQHEwNNVFYxDzAN" 428 + "BgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHQW5kcm9pZDEUMBIGA1UEAxMLVGVzdCBDbGllbnQwgZ8w" 429 + "DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIK3Q+KiFbmCGg422TAo4gggdhMH6FJhiuz8DxRyeMKR" 430 + "UAfP4MK0wtc8N42waZ6OKvxpBFUy0BRfBsX0GD4Ku99yu9/tavSigTraeJtwV3WWRRjIqk7L3wX5" 431 + "cmgS2KSD43Y0rNUKrko26lnt9N4qiYRBSj+tcAN3Lx9+ptqk1LApAgMBAAEwDQYJKoZIhvcNAQEE" 432 + "BQADgYEANb7Q1GVSuy1RPJ0FmiXoMYCCtvlRLkmJphwxovK0cAQK12Vll+yAzBhHiQHy/RA11mng" 433 + "wYudC7u3P8X/tBT8GR1Yk7QW3KgFyPafp3lQBBCraSsfrjKj+dCLig1uBLUr4f68W8VFWZWWTHqp" 434 + "NMGpCX6qmjbkJQLVK/Yfo1ePaUexPSOX0G9m8+DoV3iyNw6at01NRw=="; 435 436 437 SSLServerSocket serverSocket; 438 MyHandshakeListener listener; 439 String host = "localhost"; 440 boolean notFinished = true; 441 SSLSession clientSession = null; 442 SSLContext clientSslContext = null; 443 String testData = "PING"; 444 445 private String PASSWORD = "android"; 446 447 /** 448 * Implements a test SSL socket server. It waits for a connection on a given 449 * port, requests client authentication (if specified), reads from the socket, 450 * and writes to the socket. 451 */ 452 class TestServer implements Runnable { 453 454 public static final int CLIENT_AUTH_NONE = 0; 455 456 public static final int CLIENT_AUTH_WANTED = 1; 457 458 public static final int CLIENT_AUTH_NEEDED = 2; 459 460 private TestTrustManager trustManager; 461 462 private Exception exception; 463 464 String keys; 465 466 private int clientAuth; 467 468 private boolean provideKeys; 469 470 private KeyStore store; 471 TestServer(boolean provideKeys, int clientAuth, String keys)472 public TestServer(boolean provideKeys, int clientAuth, String keys) throws Exception { 473 this.keys = keys; 474 this.clientAuth = clientAuth; 475 this.provideKeys = provideKeys; 476 477 trustManager = new TestTrustManager(); 478 479 store = provideKeys ? getKeyStore(keys) : null; 480 KeyManager[] keyManagers = store != null ? getKeyManagers(store) : null; 481 TrustManager[] trustManagers = new TrustManager[] { trustManager }; 482 483 SSLContext sslContext = SSLContext.getInstance("TLS"); 484 sslContext.init(keyManagers, trustManagers, null); 485 486 serverSocket = (SSLServerSocket)sslContext.getServerSocketFactory().createServerSocket(); 487 488 if (clientAuth == CLIENT_AUTH_WANTED) { 489 serverSocket.setWantClientAuth(true); 490 } else if (clientAuth == CLIENT_AUTH_NEEDED) { 491 serverSocket.setNeedClientAuth(true); 492 } else { 493 serverSocket.setWantClientAuth(false); 494 } 495 496 serverSocket.bind(null); 497 } 498 run()499 public void run() { 500 try { 501 SSLSocket clientSocket = (SSLSocket)serverSocket.accept(); 502 503 InputStream istream = clientSocket.getInputStream(); 504 byte[] buffer = new byte[1024]; 505 istream.read(buffer); 506 507 OutputStream ostream = clientSocket.getOutputStream(); 508 ostream.write(testData.getBytes()); 509 ostream.flush(); 510 511 while (notFinished) { 512 Thread.currentThread().sleep(500); 513 } 514 515 clientSocket.close(); 516 serverSocket.close(); 517 518 } catch (Exception ex) { 519 exception = ex; 520 } 521 } 522 getException()523 public Exception getException() { 524 return exception; 525 } 526 getChain()527 public javax.security.cert.X509Certificate[] getChain() { 528 return trustManager.getChain(); 529 } 530 getStore()531 public KeyStore getStore() { 532 return store; 533 } 534 535 } 536 537 /** 538 * Implements a test SSL socket client. It opens a connection to localhost on 539 * a given port, writes to the socket, and reads from the socket. 540 */ 541 class TestClient implements Runnable { 542 543 private TestTrustManager trustManager; 544 545 private Exception exception; 546 547 private String keys; 548 549 private boolean provideKeys; 550 551 private KeyStore store; 552 TestClient(boolean provideKeys, String keys)553 public TestClient(boolean provideKeys, String keys) { 554 this.keys = keys; 555 this.provideKeys = provideKeys; 556 557 trustManager = new TestTrustManager(); 558 } 559 run()560 public void run() { 561 try { 562 store = provideKeys ? getKeyStore(keys) : null; 563 KeyManager[] keyManagers = store != null ? getKeyManagers(store) : null; 564 TrustManager[] trustManagers = new TrustManager[] { trustManager }; 565 566 clientSslContext = SSLContext.getInstance("TLS"); 567 clientSslContext.init(keyManagers, trustManagers, null); 568 569 SSLSocket socket = (SSLSocket)clientSslContext.getSocketFactory().createSocket(); 570 571 socket.connect(serverSocket.getLocalSocketAddress()); 572 OutputStream ostream = socket.getOutputStream(); 573 ostream.write(testData.getBytes()); 574 ostream.flush(); 575 576 InputStream istream = socket.getInputStream(); 577 byte[] buffer = new byte[1024]; 578 istream.read(buffer); 579 580 clientSession = socket.getSession(); 581 while (notFinished) { 582 Thread.currentThread().sleep(500); 583 } 584 socket.close(); 585 586 } catch (Exception ex) { 587 exception = ex; 588 } 589 } 590 getException()591 public Exception getException() { 592 return exception; 593 } 594 getChain()595 public javax.security.cert.X509Certificate[] getChain() { 596 return trustManager.getChain(); 597 } 598 getStore()599 public KeyStore getStore() { 600 return store; 601 } 602 } 603 604 /** 605 * Loads a keystore from a base64-encoded String. Returns the KeyManager[] 606 * for the result. 607 */ getKeyStore(String keys)608 private KeyStore getKeyStore(String keys) throws Exception { 609 byte[] bytes = Base64.getDecoder().decode(keys.getBytes()); 610 InputStream inputStream = new ByteArrayInputStream(bytes); 611 612 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 613 keyStore.load(inputStream, PASSWORD.toCharArray()); 614 inputStream.close(); 615 return keyStore; 616 } 617 618 /** 619 * Loads a keystore from a base64-encoded String. Returns the KeyManager[] 620 * for the result. 621 */ getKeyManagers(KeyStore keyStore)622 private KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception { 623 String algorithm = KeyManagerFactory.getDefaultAlgorithm(); 624 KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(algorithm); 625 keyManagerFactory.init(keyStore, PASSWORD.toCharArray()); 626 627 return keyManagerFactory.getKeyManagers(); 628 } 629 assertSSLSessionsEqual(SSLSession a, SSLSession b)630 public static void assertSSLSessionsEqual(SSLSession a, SSLSession b) throws Exception { 631 assertEquals(a.getApplicationBufferSize(), b.getApplicationBufferSize()); 632 assertEquals(a.getCipherSuite(), b.getCipherSuite()); 633 assertEquals(a.getCreationTime(), b.getCreationTime()); 634 assertEquals(Arrays.toString(a.getId()), Arrays.toString(b.getId())); 635 assertEquals(a.getLastAccessedTime(), b.getLastAccessedTime()); 636 assertEquals(Arrays.toString(a.getLocalCertificates()), 637 Arrays.toString(b.getLocalCertificates())); 638 assertEquals(a.getLocalPrincipal(), b.getLocalPrincipal()); 639 assertEquals(a.getPacketBufferSize(), b.getPacketBufferSize()); 640 assertEquals(Arrays.toString(a.getPeerCertificateChain()), 641 Arrays.toString(b.getPeerCertificateChain())); 642 assertEquals(Arrays.toString(a.getPeerCertificates()), 643 Arrays.toString(b.getPeerCertificates())); 644 assertEquals(a.getPeerHost(), b.getPeerHost()); 645 assertEquals(a.getPeerPort(), b.getPeerPort()); 646 assertEquals(a.getPeerPrincipal(), b.getPeerPrincipal()); 647 assertEquals(a.getProtocol(), b.getProtocol()); 648 assertEquals(Arrays.toString(a.getValueNames()), Arrays.toString(b.getValueNames())); 649 for (String name : a.getValueNames()) { 650 assertEquals(a.getValue(name), b.getValue(name)); 651 } 652 } 653 assertExtendedSSLSessionsEqual(ExtendedSSLSession a, ExtendedSSLSession b)654 private static void assertExtendedSSLSessionsEqual(ExtendedSSLSession a, ExtendedSSLSession b) 655 throws Exception { 656 assertSSLSessionsEqual(a, b); 657 assertEquals(Arrays.toString(a.getLocalSupportedSignatureAlgorithms()), 658 Arrays.toString(b.getLocalSupportedSignatureAlgorithms())); 659 assertEquals(Arrays.toString(a.getPeerSupportedSignatureAlgorithms()), 660 Arrays.toString(b.getPeerSupportedSignatureAlgorithms())); 661 662 if (a.getRequestedServerNames() == null) { 663 assertNull(b.getRequestedServerNames()); 664 } else { 665 assertEquals(a.getRequestedServerNames().size(), b.getRequestedServerNames().size()); 666 for (int i = 0; i < a.getRequestedServerNames().size(); i++) { 667 assertEquals(a.getRequestedServerNames().get(i), 668 b.getRequestedServerNames().get(i)); 669 } 670 } 671 } 672 } 673