1 /*
   2  * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 6223624
  27  * @summary SSLSocket.setUseClientMode() fails to throw expected
  28  *        IllegalArgumentException
  29  * @run main/othervm SetClientMode
  30  *
  31  *     SunJSSE does not support dynamic system properties, no way to re-use
  32  *     system properties in samevm/agentvm mode.
  33  */
  34 
  35 /*
  36  * Attempts to replicate a TCK test failure which creates SSLServerSockets
  37  * and then runs client threads which connect and start handshaking. Once
  38  * handshaking is begun the server side attempts to invoke
  39  * SSLSocket.setUseClientMode() on one or the other of the ends of the
  40  * connection, expecting an IllegalArgumentException.
  41  *
  42  * If the server side of the connection tries setUseClientMode() we
  43  * see the expected exception. If the setting is tried on the
  44  * client side SSLSocket, we do *not* see the exception, except
  45  * occasionally on the very first iteration.
  46  */
  47 
  48 import java.io.*;
  49 import java.lang.*;
  50 import java.net.*;
  51 import javax.net.ssl.*;
  52 import java.security.*;
  53 import java.security.cert.*;
  54 
  55 public class SetClientMode {
  56     private static String[] algorithms = {"TLS", "SSL", "SSLv3", "TLS"};
  57     volatile int serverPort = 0;
  58 
  59     /*
  60      * Where do we find the keystores?
  61      */
  62     static String pathToStores = "../../../../javax/net/ssl/etc";
  63     static String keyStoreFile = "keystore";
  64     static String trustStoreFile = "truststore";
  65     static String passwd = "passphrase";
  66 
  67 
  68     public SetClientMode() {
  69         // trivial constructor
  70     }
  71 
  72     public static void main(String[] args) throws Exception {
  73         String keyFilename =
  74             System.getProperty("test.src", "./") + "/" + pathToStores +
  75                 "/" + keyStoreFile;
  76         String trustFilename =
  77             System.getProperty("test.src", "./") + "/" + pathToStores +
  78                 "/" + trustStoreFile;
  79 
  80         System.setProperty("javax.net.ssl.keyStore", keyFilename);
  81         System.setProperty("javax.net.ssl.keyStorePassword", passwd);
  82         System.setProperty("javax.net.ssl.trustStore", trustFilename);
  83         System.setProperty("javax.net.ssl.trustStorePassword", passwd);
  84 
  85         new SetClientMode().run();
  86     }
  87 
  88     public void run() throws Exception {
  89         for (int i = 0; i < algorithms.length; i++) {
  90             testCombo( algorithms[i] );
  91         }
  92     }
  93 
  94     public void testCombo(String algorithm) throws Exception {
  95         Exception modeException = null ;
  96 
  97         // Create a server socket
  98         SSLServerSocketFactory ssf =
  99             (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
 100         SSLServerSocket serverSocket =
 101             (SSLServerSocket)ssf.createServerSocket(serverPort);
 102         serverPort = serverSocket.getLocalPort();
 103 
 104         // Create a client socket
 105         SSLSocketFactory sf = (SSLSocketFactory)SSLSocketFactory.getDefault();
 106         SSLSocket clientSocket = (SSLSocket)sf.createSocket(
 107                                 InetAddress.getLocalHost(),
 108                                 serverPort );
 109 
 110         // Create a client which will use the SSLSocket to talk to the server
 111         SocketClient client = new SocketClient(clientSocket);
 112 
 113         // Start the client and then accept any connection
 114         client.start();
 115 
 116         SSLSocket connectedSocket = (SSLSocket)serverSocket.accept();
 117 
 118         // force handshaking to complete
 119         connectedSocket.getSession();
 120 
 121         try {
 122             // Now try invoking setClientMode() on one
 123             // or the other of our two sockets. We expect
 124             // to see an IllegalArgumentException because
 125             // handshaking has begun.
 126             clientSocket.setUseClientMode(false);
 127 
 128             modeException = new Exception("no IllegalArgumentException");
 129         } catch (IllegalArgumentException iae) {
 130             System.out.println("succeeded, we can't set the client mode");
 131         } catch (Exception e) {
 132             modeException = e;
 133         } finally {
 134             // Shut down.
 135             connectedSocket.close();
 136             serverSocket.close();
 137 
 138             if (modeException != null) {
 139                 throw modeException;
 140             }
 141         }
 142 
 143         return;
 144     }
 145 
 146     // A thread-based client which does nothing except
 147     // start handshaking on the socket it's given.
 148     class SocketClient extends Thread {
 149         SSLSocket clientsideSocket;
 150         Exception clientException = null;
 151         boolean done = false;
 152 
 153         public SocketClient( SSLSocket s ) {
 154             clientsideSocket = s;
 155         }
 156 
 157         public void run() {
 158             try {
 159                 clientsideSocket.startHandshake();
 160 
 161                 // If we were to invoke setUseClientMode()
 162                 // here, the expected exception will happen.
 163                 //clientsideSocket.getSession();
 164                 //clientsideSocket.setUseClientMode( false );
 165             } catch ( Exception e ) {
 166                 e.printStackTrace();
 167                 clientException = e;
 168             } finally {
 169                 done = true;
 170                 try {
 171                     clientsideSocket.close();
 172                 } catch ( IOException e ) {
 173                     // eat it
 174                 }
 175             }
 176             return;
 177         }
 178 
 179         boolean isDone() {
 180             return done;
 181         }
 182 
 183         Exception getException() {
 184             return clientException;
 185         }
 186     }
 187 }