Home | History | Annotate | Download | only in jsse
      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.xnet.provider.jsse;
     19 
     20 import java.io.IOException;
     21 import java.io.InputStream;
     22 import java.io.OutputStream;
     23 import java.util.Arrays;
     24 import javax.net.ssl.HandshakeCompletedEvent;
     25 import javax.net.ssl.HandshakeCompletedListener;
     26 import javax.net.ssl.SSLContext;
     27 import javax.net.ssl.SSLServerSocket;
     28 import javax.net.ssl.SSLSocket;
     29 
     30 import junit.framework.Test;
     31 import junit.framework.TestCase;
     32 import junit.framework.TestSuite;
     33 
     34 /**
     35  * SSLSocketImplTest
     36  */
     37 public 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      *
    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                 @Override
    193                 public void run() {
    194                     InputStream is = null;
    195                     OutputStream os = null;
    196                     SSLSocket s = null;
    197                     try {
    198                         s = (SSLSocket) ss.accept();
    199                         if (doLog) {
    200                             System.out.println("Socket accepted: " + s);
    201                         }
    202                         is = s.getInputStream();
    203                         os = s.getOutputStream();
    204                         // send the message to the client
    205                         os.write(server_message.getBytes());
    206                         // read the response
    207                         byte[] buff = new byte[client_message.length()];
    208                         int len = is.read(buff);
    209                         if (doLog) {
    210                             System.out.println("Received message of length "
    211                                     + len + ": '" + new String(buff, 0, len) + "'");
    212                         }
    213                         assertTrue("Read message does not equal to expected",
    214                                 Arrays.equals(client_message.getBytes(), buff));
    215                         os.write(-1);
    216                         assertEquals("Read data differs from expected",
    217                                 255, is.read());
    218                         if (doLog) {
    219                             System.out.println("Server is closed: "
    220                                     + s.isClosed());
    221                         }
    222                         assertEquals("Returned value should be -1",
    223                                 // initiate an exchange of closure alerts
    224                                 -1, is.read());
    225                         if (doLog) {
    226                             System.out.println("Server is closed: "
    227                                     + s.isClosed());
    228                         }
    229                         assertEquals("Returned value should be -1",
    230                                 // initiate an exchange of closure alerts
    231                                 -1, is.read());
    232                     } catch (Throwable e) {
    233                         synchronized (throwed) {
    234                             if (doLog) {
    235                                 e.printStackTrace();
    236                             }
    237                             if (throwed[0] == null) {
    238                                 throwed[0] = e;
    239                             }
    240                         }
    241                     } finally {
    242                         try {
    243                             if (is != null) {
    244                                 is.close();
    245                             }
    246                         } catch (IOException ex) {
    247                         }
    248                         try {
    249                             if (os != null) {
    250                                 os.close();
    251                             }
    252                         } catch (IOException ex) {
    253                         }
    254                         try {
    255                             if (s != null) {
    256                                 s.close();
    257                             }
    258                         } catch (IOException ex) {
    259                         }
    260                     }
    261                 }
    262             };
    263 
    264             client = new Thread() {
    265                 @Override
    266                 public void run() {
    267                     InputStream is = null;
    268                     OutputStream os = null;
    269                     try {
    270                         assertTrue("Client was not connected", s.isConnected());
    271                         if (doLog) {
    272                             System.out.println("Client connected");
    273                         }
    274                         is = s.getInputStream();
    275                         os = s.getOutputStream();
    276                         s.startHandshake();
    277                         if (doLog) {
    278                             System.out.println("Client: HS was done");
    279                         }
    280                         // read the message from the server
    281                         byte[] buff = new byte[server_message.length()];
    282                         int len = is.read(buff);
    283                         if (doLog) {
    284                             System.out.println("Received message of length "
    285                                     + len + ": '" + new String(buff, 0, len) + "'");
    286                         }
    287                         assertTrue("Read message does not equal to expected",
    288                                 Arrays.equals(server_message.getBytes(), buff));
    289                         // send the response
    290                         buff = (" " + client_message + " ").getBytes();
    291                         os.write(buff, 1, buff.length - 2);
    292                         assertEquals("Read data differs from expected",
    293                                 255, is.read());
    294                         os.write(-1);
    295                         if (doLog) {
    296                             System.out.println("\n======== Closing ========");
    297                         }
    298                         if (doLog) {
    299                             System.out.println("Client is closed: "
    300                                     + s.isClosed());
    301                         }
    302                         s.close();
    303                         if (doLog) {
    304                             System.out.println("Client is closed: "
    305                                     + s.isClosed());
    306                         }
    307                     } catch (Throwable e) {
    308                         synchronized (throwed) {
    309                             if (doLog) {
    310                                 e.printStackTrace();
    311                             }
    312                             if (throwed[0] == null) {
    313                                 throwed[0] = e;
    314                             }
    315                         }
    316                     } finally {
    317                         try {
    318                             if (is != null) {
    319                                 is.close();
    320                             }
    321                         } catch (IOException ex) {
    322                         }
    323                         try {
    324                             if (os != null) {
    325                                 os.close();
    326                             }
    327                         } catch (IOException ex) {
    328                         }
    329                         try {
    330                             if (s != null) {
    331                                 s.close();
    332                             }
    333                         } catch (IOException ex) {
    334                         }
    335                     }
    336                 }
    337             };
    338 
    339             server.start();
    340             client.start();
    341 
    342             while (server.isAlive() || client.isAlive()) {
    343                 if (throwed[0] != null) {
    344                     throw throwed[0];
    345                 }
    346                 try {
    347                     Thread.sleep(500);
    348                 } catch (Exception e) {
    349                 }
    350             }
    351         } finally {
    352             if (server != null) {
    353                 server.stop();
    354             }
    355             if (client != null) {
    356                 client.stop();
    357             }
    358         }
    359         if (throwed[0] != null) {
    360             throw throwed[0];
    361         }
    362     }
    363 
    364     public static Test suite() {
    365         return new TestSuite(SSLSocketFunctionalTest.class);
    366     }
    367 
    368 }
    369