SSLSocketFunctionalTest.java revision 561ee011997c6c2f1befbfaa9d5f0a99771c1d63
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 org.apache.harmony.xnet.provider.jsse; 19 20import java.io.IOException; 21import java.io.InputStream; 22import java.io.OutputStream; 23import java.util.Arrays; 24import javax.net.ssl.HandshakeCompletedEvent; 25import javax.net.ssl.HandshakeCompletedListener; 26import javax.net.ssl.SSLContext; 27import javax.net.ssl.SSLServerSocket; 28import javax.net.ssl.SSLSocket; 29 30import junit.framework.Test; 31import junit.framework.TestCase; 32import junit.framework.TestSuite; 33 34/** 35 * SSLSocketImplTest 36 */ 37public class SSLSocketFunctionalTest extends TestCase { 38 39 /** 40 * The cipher suites used for functionality testing. 41 */ 42 private String[] cipher_suites = { 43 "RSA_WITH_RC4_128_MD5", 44 "RSA_WITH_DES_CBC_SHA", 45 "DH_anon_EXPORT_WITH_DES40_CBC_SHA" 46 }; 47 48 // turn on/off the debug logging 49 private boolean doLog = false; 50 51 /** 52 * Sets up the test case. 53 */ 54 @Override 55 public void setUp() throws Exception { 56 if (doLog) { 57 System.out.println("========================"); 58 System.out.println("====== Running the test: " + getName()); 59 System.out.println("========================"); 60 } 61 } 62 63 public void testContextInitialized2() throws Throwable { 64 doTestSelfInteraction(JSSETestData.getContext()); 65 } 66 67 public void doTestInteraction(SSLContext context, SSLContext ctx_other) 68 throws Throwable { 69 SSLContext ctx1, ctx2; 70 71 ctx1 = context; 72 ctx2 = ctx_other; 73 74 int k=1; 75 76 SSLServerSocket ssocket = (SSLServerSocket) ctx1 77 .getServerSocketFactory().createServerSocket(0); 78 ssocket.setUseClientMode(false); 79 ssocket.setEnabledCipherSuites( 80 ((k & 1) > 0) 81 ? new String[] {"TLS_"+cipher_suites[0]} 82 : new String[] {"SSL_"+cipher_suites[0]}); 83 84 SSLSocket csocket = (SSLSocket) ctx2 85 .getSocketFactory().createSocket("localhost", 86 ssocket.getLocalPort()); 87 csocket.setEnabledProtocols(new String[] {"TLSv1"}); 88 csocket.setUseClientMode(true); 89 csocket.setEnabledCipherSuites( 90 (((k & 2) >> 1) > 0) 91 ? new String[] {"TLS_"+cipher_suites[0]} 92 : new String[] {"SSL_"+cipher_suites[0]}); 93 doTest(ssocket, csocket); 94 } 95 96 public void _doTestInteraction(SSLContext context, SSLContext ctx_other) 97 throws Throwable { 98 for (int i=0; i<cipher_suites.length; i++) { 99 if (doLog) { 100 System.out.println("======== Checking the work on cipher: " 101 + cipher_suites[i]); 102 } 103 SSLContext ctx1, ctx2; 104 // k: 00, 01, 10, 11; 105 // where 1 means implementation under the test, 106 // 0 - another implementation to interract with 107 for (int k=0; k<4; k++) { 108 if (doLog) { 109 System.out.println("======== "+(k & 1)+" "+((k & 2) >> 1)); 110 } 111 ctx1 = ((k & 1) > 0) ? context : ctx_other; 112 ctx2 = (((k & 2) >> 1) > 0) ? context : ctx_other; 113 114 SSLServerSocket ssocket = (SSLServerSocket) ctx1 115 .getServerSocketFactory().createServerSocket(0); 116 ssocket.setUseClientMode(false); 117 ssocket.setEnabledCipherSuites( 118 ((k & 1) > 0) 119 ? new String[] {"TLS_"+cipher_suites[i]} 120 : new String[] {"SSL_"+cipher_suites[i]}); 121 122 SSLSocket csocket = (SSLSocket) ctx2 123 .getSocketFactory().createSocket("localhost", 124 ssocket.getLocalPort()); 125 csocket.setEnabledProtocols(new String[] {"TLSv1"}); 126 csocket.setUseClientMode(true); 127 csocket.setEnabledCipherSuites( 128 (((k & 2) >> 1) > 0) 129 ? new String[] {"TLS_"+cipher_suites[i]} 130 : new String[] {"SSL_"+cipher_suites[i]}); 131 doTest(ssocket, csocket); 132 } 133 } 134 } 135 136 /** 137 * Tests the interaction with other implementation. 138 */ 139 public void doTestSelfInteraction(SSLContext context) 140 throws Throwable { 141 String[] protocols = {"SSLv3", "TLSv1"}; 142 for (int i=0; i<cipher_suites.length; i++) { 143 for (int j=0; j<2; j++) { 144 if (doLog) { 145 System.out.println("======= " + cipher_suites[i]); 146 } 147 SSLServerSocket ssocket = (SSLServerSocket) context 148 .getServerSocketFactory().createServerSocket(0); 149 ssocket.setUseClientMode(false); 150 ssocket.setEnabledProtocols(new String[] {protocols[j]}); 151 ssocket.setEnabledCipherSuites( 152 new String[] {"TLS_"+cipher_suites[i]}); 153 154 SSLSocket csocket = (SSLSocket) context 155 .getSocketFactory().createSocket("localhost", 156 ssocket.getLocalPort()); 157 csocket.setEnabledProtocols(new String[] {protocols[j]}); 158 csocket.setUseClientMode(true); 159 csocket.setEnabledCipherSuites( 160 new String[] {"TLS_"+cipher_suites[i]}); 161 162 doTest(ssocket, csocket); 163 } 164 } 165 } 166 167 private static class HandshakeListener 168 implements HandshakeCompletedListener { 169 boolean compleated = false; 170 171 public void handshakeCompleted(HandshakeCompletedEvent event) { 172 compleated = true; 173 } 174 } 175 176 /** 177 * Performs SSL connection between the sockets 178 * @return 179 */ 180 public void doTest(SSLServerSocket ssocket, SSLSocket csocket) 181 throws Throwable { 182 final String server_message = "Hello from SSL Server Socket!"; 183 final String client_message = "Hello from SSL Socket!"; 184 Thread server = null; 185 Thread client = null; 186 final Throwable[] throwed = new Throwable[1]; 187 try { 188 final SSLServerSocket ss = ssocket; 189 final SSLSocket s = csocket; 190 server = new Thread() { 191 @Override 192 public void run() { 193 InputStream is = null; 194 OutputStream os = null; 195 SSLSocket s = null; 196 try { 197 s = (SSLSocket) ss.accept(); 198 if (doLog) { 199 System.out.println("Socket accepted: " + s); 200 } 201 is = s.getInputStream(); 202 os = s.getOutputStream(); 203 // send the message to the client 204 os.write(server_message.getBytes()); 205 // read the response 206 byte[] buff = new byte[client_message.length()]; 207 int len = is.read(buff); 208 if (doLog) { 209 System.out.println("Received message of length " 210 + len + ": '" + new String(buff, 0, len)+"'"); 211 } 212 assertTrue("Read message does not equal to expected", 213 Arrays.equals(client_message.getBytes(), buff)); 214 os.write(-1); 215 assertEquals("Read data differs from expected", 216 255, is.read()); 217 if (doLog) { 218 System.out.println("Server is closed: " 219 +s.isClosed()); 220 } 221 assertEquals("Returned value should be -1", 222 // initiate an exchange of closure alerts 223 -1, is.read()); 224 if (doLog) { 225 System.out.println("Server is closed: " 226 +s.isClosed()); 227 } 228 assertEquals("Returned value should be -1", 229 // initiate an exchange of closure alerts 230 -1, is.read()); 231 } catch (Throwable e) { 232 synchronized (throwed) { 233 if (doLog) { 234 e.printStackTrace(); 235 } 236 if (throwed[0] == null) { 237 throwed[0] = e; 238 } 239 } 240 } finally { 241 try { 242 if (is != null) { 243 is.close(); 244 } 245 } catch (IOException ex) {} 246 try { 247 if (os != null) { 248 os.close(); 249 } 250 } catch (IOException ex) {} 251 try { 252 if (s != null) { 253 s.close(); 254 } 255 } catch (IOException ex) {} 256 } 257 } 258 }; 259 260 client = new Thread() { 261 @Override 262 public void run() { 263 InputStream is = null; 264 OutputStream os = null; 265 try { 266 assertTrue("Client was not connected", s.isConnected()); 267 if (doLog) { 268 System.out.println("Client connected"); 269 } 270 is = s.getInputStream(); 271 os = s.getOutputStream(); 272 s.startHandshake(); 273 if (doLog) { 274 System.out.println("Client: HS was done"); 275 } 276 // read the message from the server 277 byte[] buff = new byte[server_message.length()]; 278 int len = is.read(buff); 279 if (doLog) { 280 System.out.println("Received message of length " 281 + len + ": '" + new String(buff, 0, len)+"'"); 282 } 283 assertTrue("Read message does not equal to expected", 284 Arrays.equals(server_message.getBytes(), buff)); 285 // send the response 286 buff = (" "+client_message+" ").getBytes(); 287 os.write(buff, 1, buff.length-2); 288 assertEquals("Read data differs from expected", 289 255, is.read()); 290 os.write(-1); 291 if (doLog) { 292 System.out.println("\n======== Closing ========"); 293 } 294 if (doLog) { 295 System.out.println("Client is closed: " 296 +s.isClosed()); 297 } 298 s.close(); 299 if (doLog) { 300 System.out.println("Client is closed: " 301 +s.isClosed()); 302 } 303 } catch (Throwable e) { 304 synchronized (throwed) { 305 if (doLog) { 306 e.printStackTrace(); 307 } 308 if (throwed[0] == null) { 309 throwed[0] = e; 310 } 311 } 312 } finally { 313 try { 314 if (is != null) { 315 is.close(); 316 } 317 } catch (IOException ex) {} 318 try { 319 if (os != null) { 320 os.close(); 321 } 322 } catch (IOException ex) {} 323 try { 324 if (s != null) { 325 s.close(); 326 } 327 } catch (IOException ex) {} 328 } 329 } 330 }; 331 332 server.start(); 333 client.start(); 334 335 while (server.isAlive() || client.isAlive()) { 336 if (throwed[0] != null) { 337 throw throwed[0]; 338 } 339 try { 340 Thread.sleep(500); 341 } catch (Exception e) { } 342 } 343 } finally { 344 if (server != null) { 345 server.stop(); 346 } 347 if (client != null) { 348 client.stop(); 349 } 350 } 351 if (throwed[0] != null) { 352 throw throwed[0]; 353 } 354 } 355 356 public static Test suite() { 357 return new TestSuite(SSLSocketFunctionalTest.class); 358 } 359 360 public static void main(String[] args) { 361 junit.textui.TestRunner.run(suite()); 362 } 363} 364 365