Path: blob/master/test/jdk/sun/security/ssl/SSLSessionImpl/ResumptionUpdateBoundValues.java
41152 views
/*1* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @library /test/lib26* @summary Test that a New Session Ticket will be generated when a27* SSLSessionBindingListener is set (boundValues)28* @run main/othervm ResumptionUpdateBoundValues29*/3031import java.io.InputStream;32import java.io.OutputStream;33import java.lang.ref.Reference;34import java.lang.ref.WeakReference;35import java.util.concurrent.ArrayBlockingQueue;3637import javax.net.ssl.SSLServerSocket;38import javax.net.ssl.SSLServerSocketFactory;39import javax.net.ssl.SSLSession;40import javax.net.ssl.SSLSessionBindingEvent;41import javax.net.ssl.SSLSessionBindingListener;42import javax.net.ssl.SSLSocket;43import javax.net.ssl.SSLSocketFactory;4445import jdk.test.lib.process.OutputAnalyzer;46import jdk.test.lib.process.ProcessTools;47import jdk.test.lib.Utils;4849public class ResumptionUpdateBoundValues {5051static boolean separateServerThread = true;5253/*54* Where do we find the keystores?55*/56static String pathToStores = "../../../../javax/net/ssl/etc/";57static String keyStoreFile = "keystore";58static String trustStoreFile = "truststore";59static String passwd = "passphrase";6061/*62* Is the server ready to serve?63*/64volatile static boolean serverReady = false;6566/*67* Turn on SSL debugging?68*/69static boolean debug = false;7071/*72* Define the server side of the test.73*74* If the server prematurely exits, serverReady will be set to true75* to avoid infinite hangs.76*/77void doServerSide() throws Exception {78SSLServerSocketFactory sslssf =79(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();80SSLServerSocket sslServerSocket =81(SSLServerSocket) sslssf.createServerSocket(serverPort);82serverPort = sslServerSocket.getLocalPort();8384/*85* Signal Client, we're ready for his connect.86*/87serverReady = true;8889while (serverReady) {90SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();91InputStream sslIS = sslSocket.getInputStream();92OutputStream sslOS = sslSocket.getOutputStream();9394sslIS.read();95sslOS.write(85);96sslOS.flush();97SSLSession sslSession = sslSocket.getSession();98SBListener sbListener = new SBListener(sslSession);99sslSession.putValue("x", sbListener);100101sslIS.read();102sslOS.write(85);103sslOS.flush();104105sslSocket.close();106}107}108109/*110* Define the client side of the test.111*112* If the server prematurely exits, serverReady will be set to true113* to avoid infinite hangs.114*/115SBListener doClientSide() throws Exception {116117/*118* Wait for server to get started.119*/120while (!serverReady) {121Thread.sleep(50);122}123124SSLSocketFactory sslsf =125(SSLSocketFactory) SSLSocketFactory.getDefault();126127try {128SSLSocket sslSocket = (SSLSocket)129sslsf.createSocket("localhost", serverPort);130InputStream sslIS = sslSocket.getInputStream();131OutputStream sslOS = sslSocket.getOutputStream();132133sslOS.write(280);134sslOS.flush();135sslIS.read();136137SSLSession sslSession = sslSocket.getSession();138System.out.printf(" sslSession: %s %n %s%n", sslSession, sslSession.getClass());139SBListener sbListener = new SBListener(sslSession);140141sslOS.write(280);142sslOS.flush();143sslIS.read();144145sslOS.write(280);146sslOS.flush();147sslIS.read();148149sslOS.close();150sslIS.close();151sslSocket.close();152153sslOS = null;154sslIS = null;155sslSession = null;156sslSocket = null;157Reference.reachabilityFence(sslOS);158Reference.reachabilityFence(sslIS);159Reference.reachabilityFence(sslSession);160Reference.reachabilityFence(sslSocket);161162return sbListener;163} catch (Exception ex) {164ex.printStackTrace();165throw ex;166}167}168169/*170* =============================================================171* The remainder is just support stuff172*/173174// use any free port by default175volatile int serverPort = 0;176177volatile Exception serverException = null;178volatile Exception clientException = null;179180public static void main(String[] args) throws Exception {181182if (args.length == 0) {183System.setProperty("test.java.opts",184"-Dtest.src=" + System.getProperty("test.src") +185" -Dtest.jdk=" + System.getProperty("test.jdk") +186" -Djavax.net.debug=ssl,handshake");187188System.out.println("test.java.opts: " +189System.getProperty("test.java.opts"));190191ProcessBuilder pb = ProcessTools.createTestJvm(192Utils.addTestJavaOpts("ResumptionUpdateBoundValues", "p"));193194OutputAnalyzer output = ProcessTools.executeProcess(pb);195try {196output.shouldContain("trigger new session ticket");197System.out.println("Found NST in debugging");198} catch (Exception e) {199throw e;200} finally {201System.out.println("-- BEGIN Stdout:");202System.out.println(output.getStdout());203System.out.println("-- END Stdout");204System.out.println("-- BEGIN Stderr:");205System.out.println(output.getStderr());206System.out.println("-- END Stderr");207}208return;209}210211String keyFilename =212System.getProperty("test.src", "./") + "/" + pathToStores +213"/" + keyStoreFile;214String trustFilename =215System.getProperty("test.src", "./") + "/" + pathToStores +216"/" + trustStoreFile;217System.setProperty("javax.net.ssl.keyStore", keyFilename);218System.setProperty("javax.net.ssl.keyStorePassword", passwd);219System.setProperty("javax.net.ssl.trustStore", trustFilename);220System.setProperty("javax.net.ssl.trustStorePassword", passwd);221222if (debug)223System.setProperty("javax.net.debug", "all");224225/*226* Start the tests.227*/228229new ResumptionUpdateBoundValues();230}231232ArrayBlockingQueue<Thread> threads = new ArrayBlockingQueue<Thread>(100);233234ArrayBlockingQueue<SBListener> sbListeners = new ArrayBlockingQueue<>(100);235236/*237* Primary constructor, used to drive remainder of the test.238*239* Fork off the other side, then do your work.240*/241ResumptionUpdateBoundValues() throws Exception {242final int count = 1;243if (separateServerThread) {244startServer(true);245startClients(true, count);246} else {247startClients(true, count);248startServer(true);249}250251/*252* Wait for other side to close down.253*/254Thread t;255while ((t = threads.take()) != Thread.currentThread()) {256System.out.printf(" joining: %s%n", t);257t.join(1000L);258}259serverReady = false;260System.gc();261System.gc();262263264SBListener listener = null;265while ((listener = sbListeners.poll()) != null) {266if (!listener.check()) {267System.out.printf(" sbListener not called on finalize: %s%n",268listener);269}270}271272/*273* When we get here, the test is pretty much over.274*275* If the main thread excepted, that propagates back276* immediately. If the other thread threw an exception, we277* should report back.278*/279if (serverException != null) {280System.out.print("Server Exception:");281throw serverException;282}283if (clientException != null) {284System.out.print("Client Exception:");285throw clientException;286}287}288289void startServer(boolean newThread) throws Exception {290if (newThread) {291Thread t = new Thread("Server") {292public void run() {293try {294doServerSide();295} catch (Exception e) {296/*297* Our server thread just died.298*299* Release the client, if not active already...300*/301System.err.println("Server died..." + e);302serverReady = true;303serverException = e;304}305}306};307threads.add(t);308t.setDaemon(true);309t.start();310} else {311doServerSide();312}313}314315void startClients(boolean newThread, int count) throws Exception {316for (int i = 0; i < count; i++) {317System.out.printf(" newClient: %d%n", i);318startClient(newThread);319}320serverReady = false;321322threads.add(Thread.currentThread()); // add ourselves at the 'end'323}324void startClient(boolean newThread) throws Exception {325if (newThread) {326Thread t = new Thread("Client") {327public void run() {328try {329sbListeners.add(doClientSide());330} catch (Exception e) {331/*332* Our client thread just died.333*/334System.err.println("Client died..." + e);335clientException = e;336}337}338};339System.out.printf(" starting: %s%n", t);340threads.add(t);341t.start();342} else {343sbListeners.add(doClientSide());344}345}346347348static class SBListener implements SSLSessionBindingListener {349private volatile int unboundNotified;350private final WeakReference<SSLSession> session;351352SBListener(SSLSession session) {353this.unboundNotified = 0;354this.session = new WeakReference<SSLSession>(session);355}356357boolean check() {358System.out.printf(" check: %s%n", this);359return unboundNotified > 0 && session.get() == null;360}361362@Override363public void valueBound(SSLSessionBindingEvent event) {364System.out.printf(" valueBound: %s%n", event.getName());365}366367@Override368public void valueUnbound(SSLSessionBindingEvent event) {369System.out.printf(" valueUnbound: %s%n", event.getName());370unboundNotified++;371}372373public String toString() {374return "count: " + unboundNotified +375", ref: " + session.get();376}377}378}379380381382