001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.xnet.provider.jsse;
019:
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.io.OutputStream;
023: import java.util.Arrays;
024: import javax.net.ssl.HandshakeCompletedEvent;
025: import javax.net.ssl.HandshakeCompletedListener;
026: import javax.net.ssl.SSLContext;
027: import javax.net.ssl.SSLServerSocket;
028: import javax.net.ssl.SSLSocket;
029:
030: import junit.framework.Test;
031: import junit.framework.TestCase;
032: import junit.framework.TestSuite;
033:
034: /**
035: * SSLSocketImplTest
036: */
037: public class SSLSocketFunctionalTest extends TestCase {
038:
039: /**
040: * The cipher suites used for functionality testing.
041: */
042: private String[] cipher_suites = { "RSA_WITH_RC4_128_MD5",
043: "RSA_WITH_DES_CBC_SHA", "DH_anon_EXPORT_WITH_DES40_CBC_SHA" };
044:
045: // turn on/off the debug logging
046: private boolean doLog = false;
047:
048: /**
049: * Sets up the test case.
050: */
051: public void setUp() throws Exception {
052: if (doLog) {
053: System.out.println("========================");
054: System.out.println("====== Running the test: " + getName());
055: System.out.println("========================");
056: }
057: }
058:
059: public void testContextInitialized2() throws Throwable {
060: doTestSelfInteraction(JSSETestData.getContext());
061: }
062:
063: public void doTestInteraction(SSLContext context,
064: SSLContext ctx_other) throws Throwable {
065: SSLContext ctx1, ctx2;
066:
067: ctx1 = context;
068: ctx2 = ctx_other;
069:
070: int k = 1;
071:
072: SSLServerSocket ssocket = (SSLServerSocket) ctx1
073: .getServerSocketFactory().createServerSocket(0);
074: ssocket.setUseClientMode(false);
075: ssocket
076: .setEnabledCipherSuites(((k & 1) > 0) ? new String[] { "TLS_"
077: + cipher_suites[0] }
078: : new String[] { "SSL_" + cipher_suites[0] });
079:
080: SSLSocket csocket = (SSLSocket) ctx2.getSocketFactory()
081: .createSocket("localhost", ssocket.getLocalPort());
082: csocket.setEnabledProtocols(new String[] { "TLSv1" });
083: csocket.setUseClientMode(true);
084: csocket
085: .setEnabledCipherSuites((((k & 2) >> 1) > 0) ? new String[] { "TLS_"
086: + cipher_suites[0] }
087: : new String[] { "SSL_" + cipher_suites[0] });
088: doTest(ssocket, csocket);
089: }
090:
091: public void _doTestInteraction(SSLContext context,
092: SSLContext ctx_other) throws Throwable {
093: for (int i = 0; i < cipher_suites.length; i++) {
094: if (doLog) {
095: System.out
096: .println("======== Checking the work on cipher: "
097: + cipher_suites[i]);
098: }
099: SSLContext ctx1, ctx2;
100: // k: 00, 01, 10, 11;
101: // where 1 means implementation under the test,
102: // 0 - another implementation to interract with
103: for (int k = 0; k < 4; k++) {
104: if (doLog) {
105: System.out.println("======== " + (k & 1) + " "
106: + ((k & 2) >> 1));
107: }
108: ctx1 = ((k & 1) > 0) ? context : ctx_other;
109: ctx2 = (((k & 2) >> 1) > 0) ? context : ctx_other;
110:
111: SSLServerSocket ssocket = (SSLServerSocket) ctx1
112: .getServerSocketFactory().createServerSocket(0);
113: ssocket.setUseClientMode(false);
114: ssocket
115: .setEnabledCipherSuites(((k & 1) > 0) ? new String[] { "TLS_"
116: + cipher_suites[i] }
117: : new String[] { "SSL_"
118: + cipher_suites[i] });
119:
120: SSLSocket csocket = (SSLSocket) ctx2.getSocketFactory()
121: .createSocket("localhost",
122: ssocket.getLocalPort());
123: csocket.setEnabledProtocols(new String[] { "TLSv1" });
124: csocket.setUseClientMode(true);
125: csocket
126: .setEnabledCipherSuites((((k & 2) >> 1) > 0) ? new String[] { "TLS_"
127: + cipher_suites[i] }
128: : new String[] { "SSL_"
129: + cipher_suites[i] });
130: doTest(ssocket, csocket);
131: }
132: }
133: }
134:
135: /**
136: * Tests the interaction with other implementation.
137: */
138: public void doTestSelfInteraction(SSLContext context)
139: throws Throwable {
140: String[] protocols = { "SSLv3", "TLSv1" };
141: for (int i = 0; i < cipher_suites.length; i++) {
142: for (int j = 0; j < 2; j++) {
143: if (doLog) {
144: System.out.println("======= " + cipher_suites[i]);
145: }
146: SSLServerSocket ssocket = (SSLServerSocket) context
147: .getServerSocketFactory().createServerSocket(0);
148: ssocket.setUseClientMode(false);
149: ssocket
150: .setEnabledProtocols(new String[] { protocols[j] });
151: ssocket.setEnabledCipherSuites(new String[] { "TLS_"
152: + cipher_suites[i] });
153:
154: SSLSocket csocket = (SSLSocket) context
155: .getSocketFactory().createSocket("localhost",
156: ssocket.getLocalPort());
157: csocket
158: .setEnabledProtocols(new String[] { protocols[j] });
159: csocket.setUseClientMode(true);
160: csocket.setEnabledCipherSuites(new String[] { "TLS_"
161: + cipher_suites[i] });
162:
163: doTest(ssocket, csocket);
164: }
165: }
166: }
167:
168: private static class HandshakeListener implements
169: HandshakeCompletedListener {
170: boolean compleated = false;
171:
172: public void handshakeCompleted(HandshakeCompletedEvent event) {
173: compleated = true;
174: }
175: }
176:
177: /**
178: * Performs SSL connection between the sockets
179: * @return
180: */
181: public void doTest(SSLServerSocket ssocket, SSLSocket csocket)
182: throws Throwable {
183: final String server_message = "Hello from SSL Server Socket!";
184: final String client_message = "Hello from SSL Socket!";
185: Thread server = null;
186: Thread client = null;
187: final Throwable[] throwed = new Throwable[1];
188: try {
189: final SSLServerSocket ss = ssocket;
190: final SSLSocket s = csocket;
191: server = new Thread() {
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
210: .println("Received message of length "
211: + len
212: + ": '"
213: + new String(buff, 0, len)
214: + "'");
215: }
216: assertTrue(
217: "Read message does not equal to expected",
218: Arrays
219: .equals(client_message
220: .getBytes(), buff));
221: os.write(-1);
222: assertEquals("Read data differs from expected",
223: 255, 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: if (doLog) {
232: System.out.println("Server is closed: "
233: + s.isClosed());
234: }
235: assertEquals("Returned value should be -1",
236: // initiate an exchange of closure alerts
237: -1, is.read());
238: } catch (Throwable e) {
239: synchronized (throwed) {
240: if (doLog) {
241: e.printStackTrace();
242: }
243: if (throwed[0] == null) {
244: throwed[0] = e;
245: }
246: }
247: } finally {
248: try {
249: if (is != null) {
250: is.close();
251: }
252: } catch (IOException ex) {
253: }
254: try {
255: if (os != null) {
256: os.close();
257: }
258: } catch (IOException ex) {
259: }
260: try {
261: if (s != null) {
262: s.close();
263: }
264: } catch (IOException ex) {
265: }
266: }
267: }
268: };
269:
270: client = new Thread() {
271: public void run() {
272: InputStream is = null;
273: OutputStream os = null;
274: try {
275: assertTrue("Client was not connected", s
276: .isConnected());
277: if (doLog) {
278: System.out.println("Client connected");
279: }
280: is = s.getInputStream();
281: os = s.getOutputStream();
282: s.startHandshake();
283: if (doLog) {
284: System.out.println("Client: HS was done");
285: }
286: // read the message from the server
287: byte[] buff = new byte[server_message.length()];
288: int len = is.read(buff);
289: if (doLog) {
290: System.out
291: .println("Received message of length "
292: + len
293: + ": '"
294: + new String(buff, 0, len)
295: + "'");
296: }
297: assertTrue(
298: "Read message does not equal to expected",
299: Arrays
300: .equals(server_message
301: .getBytes(), buff));
302: // send the response
303: buff = (" " + client_message + " ").getBytes();
304: os.write(buff, 1, buff.length - 2);
305: assertEquals("Read data differs from expected",
306: 255, is.read());
307: os.write(-1);
308: if (doLog) {
309: System.out
310: .println("\n======== Closing ========");
311: }
312: if (doLog) {
313: System.out.println("Client is closed: "
314: + s.isClosed());
315: }
316: s.close();
317: if (doLog) {
318: System.out.println("Client is closed: "
319: + s.isClosed());
320: }
321: } catch (Throwable e) {
322: synchronized (throwed) {
323: if (doLog) {
324: e.printStackTrace();
325: }
326: if (throwed[0] == null) {
327: throwed[0] = e;
328: }
329: }
330: } finally {
331: try {
332: if (is != null) {
333: is.close();
334: }
335: } catch (IOException ex) {
336: }
337: try {
338: if (os != null) {
339: os.close();
340: }
341: } catch (IOException ex) {
342: }
343: try {
344: if (s != null) {
345: s.close();
346: }
347: } catch (IOException ex) {
348: }
349: }
350: }
351: };
352:
353: server.start();
354: client.start();
355:
356: while (server.isAlive() || client.isAlive()) {
357: if (throwed[0] != null) {
358: throw throwed[0];
359: }
360: try {
361: Thread.sleep(500);
362: } catch (Exception e) {
363: }
364: }
365: } finally {
366: if (server != null) {
367: server.stop();
368: }
369: if (client != null) {
370: client.stop();
371: }
372: }
373: if (throwed[0] != null) {
374: throw throwed[0];
375: }
376: }
377:
378: public static Test suite() {
379: return new TestSuite(SSLSocketFunctionalTest.class);
380: }
381:
382: public static void main(String[] args) {
383: junit.textui.TestRunner.run(suite());
384: }
385: }
|