1 /*
   2  * Copyright (c) 2001, 2019, 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 // SunJSSE does not support dynamic system properties, no way to re-use
  26 // system properties in samevm/agentvm mode.
  27 //
  28 
  29 /*
  30  * @test
  31  * @bug 4403428 8190492
  32  * @summary Invalidating JSSE session on server causes SSLProtocolException
  33  * @run main/othervm InvalidateServerSessionRenegotiate SSLv3
  34  * @run main/othervm InvalidateServerSessionRenegotiate TLSv1
  35  * @run main/othervm InvalidateServerSessionRenegotiate TLSv1.1
  36  * @run main/othervm InvalidateServerSessionRenegotiate TLSv1.2
  37  * @author Brad Wetmore
  38  */
  39 
  40 import java.io.*;
  41 import java.net.*;
  42 import java.security.Security;
  43 import javax.net.ssl.*;
  44 
  45 public class InvalidateServerSessionRenegotiate implements
  46         HandshakeCompletedListener {
  47 
  48     static byte handshakesCompleted = 0;
  49 
  50     /*
  51      * Define what happens when handshaking is completed
  52      */
  53     public void handshakeCompleted(HandshakeCompletedEvent event) {
  54         synchronized (this) {
  55             handshakesCompleted++;
  56             System.out.println("Session: " + event.getSession().toString());
  57             System.out.println("Seen handshake completed #" +
  58                 handshakesCompleted);
  59         }
  60     }
  61 
  62     /*
  63      * =============================================================
  64      * Set the various variables needed for the tests, then
  65      * specify what tests to run on each side.
  66      */
  67 
  68     /*
  69      * Should we run the client or server in a separate thread?
  70      * Both sides can throw exceptions, but do you have a preference
  71      * as to which side should be the main thread.
  72      */
  73     static boolean separateServerThread = false;
  74 
  75     /*
  76      * Where do we find the keystores?
  77      */
  78     static String pathToStores = "../../../../javax/net/ssl/etc";
  79     static String keyStoreFile = "keystore";
  80     static String trustStoreFile = "truststore";
  81     static String passwd = "passphrase";
  82 
  83     /*
  84      * Is the server ready to serve?
  85      */
  86     volatile static boolean serverReady = false;
  87 
  88     /*
  89      * Turn on SSL debugging?
  90      */
  91     static boolean debug = false;
  92 
  93     /*
  94      * If the client or server is doing some kind of object creation
  95      * that the other side depends on, and that thread prematurely
  96      * exits, you may experience a hang.  The test harness will
  97      * terminate all hung threads after its timeout has expired,
  98      * currently 3 minutes by default, but you might try to be
  99      * smart about it....
 100      */
 101 
 102     /*
 103      * Define the server side of the test.
 104      *
 105      * If the server prematurely exits, serverReady will be set to true
 106      * to avoid infinite hangs.
 107      */
 108     void doServerSide() throws Exception {
 109         SSLServerSocketFactory sslssf =
 110             (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
 111         SSLServerSocket sslServerSocket =
 112             (SSLServerSocket) sslssf.createServerSocket(serverPort);
 113 
 114         serverPort = sslServerSocket.getLocalPort();
 115 
 116         /*
 117          * Signal Client, we're ready for his connect.
 118          */
 119         serverReady = true;
 120 
 121         SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
 122         sslSocket.addHandshakeCompletedListener(this);
 123 
 124         // Enable all supported protocols on server side to test SSLv3
 125         if ("SSLv3".equals(tlsProtocol)) {
 126             sslSocket.setEnabledProtocols(sslSocket.getSupportedProtocols());
 127         }
 128 
 129         InputStream sslIS = sslSocket.getInputStream();
 130         OutputStream sslOS = sslSocket.getOutputStream();
 131 
 132         for (int i = 0; i < 10; i++) {
 133             sslIS.read();
 134             sslOS.write(85);
 135             sslOS.flush();
 136         }
 137 
 138         System.out.println("invalidating");
 139         sslSocket.getSession().invalidate();
 140         System.out.println("starting new handshake");
 141         sslSocket.startHandshake();
 142 
 143         for (int i = 0; i < 10; i++) {
 144             System.out.println("sending/receiving data, iteration: " + i);
 145             sslIS.read();
 146             sslOS.write(85);
 147             sslOS.flush();
 148         }
 149 
 150         sslSocket.close();
 151     }
 152 
 153     /*
 154      * Define the client side of the test.
 155      *
 156      * If the server prematurely exits, serverReady will be set to true
 157      * to avoid infinite hangs.
 158      */
 159     void doClientSide() throws Exception {
 160 
 161         /*
 162          * Wait for server to get started.
 163          */
 164         while (!serverReady) {
 165             Thread.sleep(50);
 166         }
 167 
 168         SSLSocketFactory sslsf =
 169             (SSLSocketFactory) SSLSocketFactory.getDefault();
 170         SSLSocket sslSocket = (SSLSocket)
 171             sslsf.createSocket("localhost", serverPort);
 172         sslSocket.setEnabledProtocols(new String[] { tlsProtocol });
 173 
 174         InputStream sslIS = sslSocket.getInputStream();
 175         OutputStream sslOS = sslSocket.getOutputStream();
 176 
 177         for (int i = 0; i < 10; i++) {
 178             sslOS.write(280);
 179             sslOS.flush();
 180             sslIS.read();
 181         }
 182 
 183         for (int i = 0; i < 10; i++) {
 184             sslOS.write(280);
 185             sslOS.flush();
 186             sslIS.read();
 187         }
 188 
 189         sslSocket.close();
 190     }
 191 
 192     /*
 193      * =============================================================
 194      * The remainder is just support stuff
 195      */
 196 
 197     // use any free port by default
 198     volatile int serverPort = 0;
 199 
 200     volatile Exception serverException = null;
 201     volatile Exception clientException = null;
 202 
 203     // the specified protocol
 204     private static String tlsProtocol;
 205 
 206     public static void main(String[] args) throws Exception {
 207         String keyFilename =
 208             System.getProperty("test.src", "./") + "/" + pathToStores +
 209                 "/" + keyStoreFile;
 210         String trustFilename =
 211             System.getProperty("test.src", "./") + "/" + pathToStores +
 212                 "/" + trustStoreFile;
 213 
 214         System.setProperty("javax.net.ssl.keyStore", keyFilename);
 215         System.setProperty("javax.net.ssl.keyStorePassword", passwd);
 216         System.setProperty("javax.net.ssl.trustStore", trustFilename);
 217         System.setProperty("javax.net.ssl.trustStorePassword", passwd);
 218 
 219         if (debug) {
 220             System.setProperty("javax.net.debug", "all");
 221         }
 222 
 223         Security.setProperty("jdk.tls.disabledAlgorithms", "");
 224 
 225         tlsProtocol = args[0];
 226 
 227         /*
 228          * Start the tests.
 229          */
 230         new InvalidateServerSessionRenegotiate();
 231     }
 232 
 233     Thread clientThread = null;
 234     Thread serverThread = null;
 235 
 236     /*
 237      * Primary constructor, used to drive remainder of the test.
 238      *
 239      * Fork off the other side, then do your work.
 240      */
 241     InvalidateServerSessionRenegotiate() throws Exception {
 242         if (separateServerThread) {
 243             startServer(true);
 244             startClient(false);
 245         } else {
 246             startClient(true);
 247             startServer(false);
 248         }
 249 
 250         /*
 251          * Wait for other side to close down.
 252          */
 253         if (separateServerThread) {
 254             serverThread.join();
 255         } else {
 256             clientThread.join();
 257         }
 258 
 259         /*
 260          * When we get here, the test is pretty much over.
 261          *
 262          * If the main thread excepted, that propagates back
 263          * immediately.  If the other thread threw an exception, we
 264          * should report back.
 265          */
 266         if (serverException != null) {
 267             System.out.print("Server Exception:");
 268             throw serverException;
 269         }
 270         if (clientException != null) {
 271             System.out.print("Client Exception:");
 272             throw clientException;
 273         }
 274 
 275         /*
 276          * Give the Handshaker Thread a chance to run
 277          */
 278         Thread.sleep(1000);
 279 
 280         synchronized (this) {
 281             if (handshakesCompleted != 2) {
 282                 throw new Exception("Didn't see 2 handshake completed events.");
 283             }
 284         }
 285     }
 286 
 287     void startServer(boolean newThread) throws Exception {
 288         if (newThread) {
 289             serverThread = new Thread() {
 290                 public void run() {
 291                     try {
 292                         doServerSide();
 293                     } catch (Exception e) {
 294                         /*
 295                          * Our server thread just died.
 296                          *
 297                          * Release the client, if not active already...
 298                          */
 299                         System.err.println("Server died...");
 300                         serverReady = true;
 301                         serverException = e;
 302                     }
 303                 }
 304             };
 305             serverThread.start();
 306         } else {
 307             doServerSide();
 308         }
 309     }
 310 
 311     void startClient(boolean newThread) throws Exception {
 312         if (newThread) {
 313             clientThread = new Thread() {
 314                 public void run() {
 315                     try {
 316                         doClientSide();
 317                     } catch (Exception e) {
 318                         /*
 319                          * Our client thread just died.
 320                          */
 321                         System.err.println("Client died...");
 322                         clientException = e;
 323                     }
 324                 }
 325             };
 326             clientThread.start();
 327         } else {
 328             doClientSide();
 329         }
 330     }
 331 }