Path: blob/master/test/jdk/javax/net/ssl/ServerName/SSLSocketExplorerFailure.java
41152 views
/*1* Copyright (c) 2012, 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// SunJSSE does not support dynamic system properties, no way to re-use25// system properties in samevm/agentvm mode.26//2728/**29* @test30* @bug 706832131* @summary Support TLS Server Name Indication (SNI) Extension in JSSE Server32* @library ../templates33* @build SSLCapabilities SSLExplorer34* @run main/othervm SSLSocketExplorerFailure SSLv2Hello,SSLv335* @run main/othervm SSLSocketExplorerFailure SSLv336* @run main/othervm SSLSocketExplorerFailure TLSv137* @run main/othervm SSLSocketExplorerFailure TLSv1.138* @run main/othervm SSLSocketExplorerFailure TLSv1.239*/4041import java.io.*;42import java.nio.*;43import java.nio.channels.*;44import java.util.*;45import java.net.*;46import javax.net.ssl.*;47import java.security.Security;4849public class SSLSocketExplorerFailure {5051/*52* =============================================================53* Set the various variables needed for the tests, then54* specify what tests to run on each side.55*/5657/*58* Should we run the client or server in a separate thread?59* Both sides can throw exceptions, but do you have a preference60* as to which side should be the main thread.61*/62static boolean separateServerThread = true;6364/*65* Where do we find the keystores?66*/67static String pathToStores = "../etc";68static String keyStoreFile = "keystore";69static String trustStoreFile = "truststore";70static String passwd = "passphrase";7172/*73* Is the server ready to serve?74*/75volatile static boolean serverReady = false;7677/*78* Turn on SSL debugging?79*/80static boolean debug = false;8182/*83* If the client or server is doing some kind of object creation84* that the other side depends on, and that thread prematurely85* exits, you may experience a hang. The test harness will86* terminate all hung threads after its timeout has expired,87* currently 3 minutes by default, but you might try to be88* smart about it....89*/9091/*92* Define the server side of the test.93*94* If the server prematurely exits, serverReady will be set to true95* to avoid infinite hangs.96*/97void doServerSide() throws Exception {9899ServerSocket serverSocket = new ServerSocket(serverPort);100101// Signal Client, we're ready for his connect.102serverPort = serverSocket.getLocalPort();103serverReady = true;104105Socket socket = serverSocket.accept();106InputStream ins = socket.getInputStream();107108byte[] buffer = new byte[0xFF];109int position = 0;110SSLCapabilities capabilities = null;111boolean failed = false;112try {113// Read the header of TLS record114while (position < SSLExplorer.RECORD_HEADER_SIZE) {115int count = SSLExplorer.RECORD_HEADER_SIZE - position;116int n = ins.read(buffer, position, count);117if (n < 0) {118throw new Exception("unexpected end of stream!");119}120position += n;121}122123int recordLength = SSLExplorer.getRequiredSize(buffer, 0, position);124if (buffer.length < recordLength) {125buffer = Arrays.copyOf(buffer, recordLength);126}127128while (position < recordLength) {129int count = recordLength - position;130int n = ins.read(buffer, position, count);131if (n < 0) {132throw new Exception("unexpected end of stream!");133}134position += n;135}136137capabilities = SSLExplorer.explore(buffer, 0, recordLength);;138if (capabilities != null) {139System.out.println("Record version: " +140capabilities.getRecordVersion());141System.out.println("Hello version: " +142capabilities.getHelloVersion());143}144145// want an I/O exception146throw new IOException("We just want a I/O exception");147} catch (Exception e) {148failed = true;149}150151// off course, the above explore failed. Faile to failure handler152SSLContext context = SSLContext.getInstance("TLS");153context.init(null, null, null);154SSLSocketFactory sslsf = context.getSocketFactory();155ByteArrayInputStream bais =156new ByteArrayInputStream(buffer, 0, position);157SSLSocket sslSocket = (SSLSocket)sslsf.createSocket(socket, bais, true);158159try {160InputStream sslIS = sslSocket.getInputStream();161OutputStream sslOS = sslSocket.getOutputStream();162163sslIS.read();164if (!failed) {165sslOS.write(85);166sslOS.flush();167} else {168sslSocket.close();169}170} catch (Exception e) {171System.out.println("server exception " + e);172} finally {173sslSocket.close();174serverSocket.close();175}176}177178179/*180* Define the client side of the test.181*182* If the server prematurely exits, serverReady will be set to true183* to avoid infinite hangs.184*/185void doClientSide() throws Exception {186187/*188* Wait for server to get started.189*/190while (!serverReady) {191Thread.sleep(50);192}193194SSLSocketFactory sslsf =195(SSLSocketFactory) SSLSocketFactory.getDefault();196SSLSocket sslSocket = (SSLSocket)197sslsf.createSocket("localhost", serverPort);198199// enable the specified TLS protocol200sslSocket.setEnabledProtocols(supportedProtocols);201202try {203InputStream sslIS = sslSocket.getInputStream();204OutputStream sslOS = sslSocket.getOutputStream();205206sslOS.write(280);207sslOS.flush();208sslIS.read();209} catch (Exception e) {210System.out.println("client exception " + e);211} finally {212sslSocket.close();213}214}215216private static String[] supportedProtocols; // supported protocols217218private static void parseArguments(String[] args) {219supportedProtocols = args[0].split(",");220}221222223/*224* =============================================================225* The remainder is just support stuff226*/227228// use any free port by default229volatile int serverPort = 0;230231volatile Exception serverException = null;232volatile Exception clientException = null;233234public static void main(String[] args) throws Exception {235Security.setProperty("jdk.tls.disabledAlgorithms", "");236Security.setProperty("jdk.certpath.disabledAlgorithms", "");237238String keyFilename =239System.getProperty("test.src", ".") + "/" + pathToStores +240"/" + keyStoreFile;241String trustFilename =242System.getProperty("test.src", ".") + "/" + pathToStores +243"/" + trustStoreFile;244245System.setProperty("javax.net.ssl.keyStore", keyFilename);246System.setProperty("javax.net.ssl.keyStorePassword", passwd);247System.setProperty("javax.net.ssl.trustStore", trustFilename);248System.setProperty("javax.net.ssl.trustStorePassword", passwd);249250if (debug)251System.setProperty("javax.net.debug", "all");252253/*254* Get the customized arguments.255*/256parseArguments(args);257258/*259* Start the tests.260*/261new SSLSocketExplorerFailure();262}263264Thread clientThread = null;265Thread serverThread = null;266267/*268* Primary constructor, used to drive remainder of the test.269*270* Fork off the other side, then do your work.271*/272SSLSocketExplorerFailure() throws Exception {273try {274if (separateServerThread) {275startServer(true);276startClient(false);277} else {278startClient(true);279startServer(false);280}281} catch (Exception e) {282// swallow for now. Show later283}284285/*286* Wait for other side to close down.287*/288if (separateServerThread) {289serverThread.join();290} else {291clientThread.join();292}293294/*295* When we get here, the test is pretty much over.296* Which side threw the error?297*/298Exception local;299Exception remote;300String whichRemote;301302if (separateServerThread) {303remote = serverException;304local = clientException;305whichRemote = "server";306} else {307remote = clientException;308local = serverException;309whichRemote = "client";310}311312/*313* If both failed, return the curthread's exception, but also314* print the remote side Exception315*/316if ((local != null) && (remote != null)) {317System.out.println(whichRemote + " also threw:");318remote.printStackTrace();319System.out.println();320throw local;321}322323if (remote != null) {324throw remote;325}326327if (local != null) {328throw local;329}330}331332void startServer(boolean newThread) throws Exception {333if (newThread) {334serverThread = new Thread() {335public void run() {336try {337doServerSide();338} catch (Exception e) {339/*340* Our server thread just died.341*342* Release the client, if not active already...343*/344System.err.println("Server died...");345serverReady = true;346serverException = e;347}348}349};350serverThread.start();351} else {352try {353doServerSide();354} catch (Exception e) {355serverException = e;356} finally {357serverReady = true;358}359}360}361362void startClient(boolean newThread) throws Exception {363if (newThread) {364clientThread = new Thread() {365public void run() {366try {367doClientSide();368} catch (Exception e) {369/*370* Our client thread just died.371*/372System.err.println("Client died...");373clientException = e;374}375}376};377clientThread.start();378} else {379try {380doClientSide();381} catch (Exception e) {382clientException = e;383}384}385}386}387388389