Path: blob/master/test/jdk/javax/net/ssl/ServerName/SSLSocketInconsistentSNI.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* @run main/othervm SSLSocketInconsistentSNI33*/3435import java.io.*;36import java.nio.*;37import java.nio.channels.*;38import java.util.*;39import java.net.*;40import javax.net.ssl.*;4142public class SSLSocketInconsistentSNI {4344/*45* =============================================================46* Set the various variables needed for the tests, then47* specify what tests to run on each side.48*/4950/*51* Should we run the client or server in a separate thread?52* Both sides can throw exceptions, but do you have a preference53* as to which side should be the main thread.54*/55static boolean separateServerThread = true;5657/*58* Where do we find the keystores?59*/60static String pathToStores = "../etc";61static String keyStoreFile = "keystore";62static String trustStoreFile = "truststore";63static String passwd = "passphrase";6465/*66* Is the server ready to serve?67*/68volatile static boolean serverReady = false;6970/*71* Turn on SSL debugging?72*/73static boolean debug = false;7475/*76* If the client or server is doing some kind of object creation77* that the other side depends on, and that thread prematurely78* exits, you may experience a hang. The test harness will79* terminate all hung threads after its timeout has expired,80* currently 3 minutes by default, but you might try to be81* smart about it....82*/8384/*85* Define the server side of the test.86*87* If the server prematurely exits, serverReady will be set to true88* to avoid infinite hangs.89*/90void doServerSide() throws Exception {91SSLServerSocketFactory sslssf =92(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();93SSLServerSocket sslServerSocket =94(SSLServerSocket) sslssf.createServerSocket(serverPort);9596SNIMatcher matcher = SNIHostName.createSNIMatcher(97serverAcceptableHostname);98Collection<SNIMatcher> matchers = new ArrayList<>(1);99matchers.add(matcher);100SSLParameters params = sslServerSocket.getSSLParameters();101params.setSNIMatchers(matchers);102sslServerSocket.setSSLParameters(params);103104serverPort = sslServerSocket.getLocalPort();105106/*107* Signal Client, we're ready for his connect.108*/109serverReady = true;110111SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();112try {113InputStream sslIS = sslSocket.getInputStream();114OutputStream sslOS = sslSocket.getOutputStream();115116sslIS.read();117sslOS.write(85);118sslOS.flush();119120throw new Exception(121"Mismatched server name indication was accepted");122} catch (SSLHandshakeException sslhe) {123// the expected unrecognized server name indication exception124} catch (IOException ioe) {125// the peer may have closed the socket because of the unmatched126// server name indication.127} finally {128sslSocket.close();129sslServerSocket.close();130}131}132133134/*135* Define the client side of the test.136*137* If the server prematurely exits, serverReady will be set to true138* to avoid infinite hangs.139*/140void doClientSide() throws Exception {141142/*143* Wait for server to get started.144*/145while (!serverReady) {146Thread.sleep(50);147}148149SSLSocketFactory sslsf =150(SSLSocketFactory) SSLSocketFactory.getDefault();151SSLSocket sslSocket = (SSLSocket)152sslsf.createSocket("localhost", serverPort);153154SNIHostName serverName = new SNIHostName(clientRequestedHostname);155List<SNIServerName> serverNames = new ArrayList<>(1);156serverNames.add(serverName);157SSLParameters params = sslSocket.getSSLParameters();158params.setServerNames(serverNames);159sslSocket.setSSLParameters(params);160161try {162InputStream sslIS = sslSocket.getInputStream();163OutputStream sslOS = sslSocket.getOutputStream();164165sslOS.write(280);166sslOS.flush();167sslIS.read();168169throw new Exception(170"Mismatched server name indication was accepted");171} catch (SSLHandshakeException sslhe) {172// the expected unrecognized server name indication exception173} catch (IOException ioe) {174// the peer may have closed the socket because of the unmatched175// server name indication.176} finally {177sslSocket.close();178}179}180181private static String clientRequestedHostname = "www.example.com";182private static String serverAcceptableHostname = "www\\.example\\.org";183184/*185* =============================================================186* The remainder is just support stuff187*/188189// use any free port by default190volatile int serverPort = 0;191192volatile Exception serverException = null;193volatile Exception clientException = null;194195public static void main(String[] args) throws Exception {196String keyFilename =197System.getProperty("test.src", ".") + "/" + pathToStores +198"/" + keyStoreFile;199String trustFilename =200System.getProperty("test.src", ".") + "/" + pathToStores +201"/" + trustStoreFile;202203System.setProperty("javax.net.ssl.keyStore", keyFilename);204System.setProperty("javax.net.ssl.keyStorePassword", passwd);205System.setProperty("javax.net.ssl.trustStore", trustFilename);206System.setProperty("javax.net.ssl.trustStorePassword", passwd);207208if (debug)209System.setProperty("javax.net.debug", "all");210211/*212* Start the tests.213*/214new SSLSocketInconsistentSNI();215}216217Thread clientThread = null;218Thread serverThread = null;219220/*221* Primary constructor, used to drive remainder of the test.222*223* Fork off the other side, then do your work.224*/225SSLSocketInconsistentSNI() throws Exception {226try {227if (separateServerThread) {228startServer(true);229startClient(false);230} else {231startClient(true);232startServer(false);233}234} catch (Exception e) {235// swallow for now. Show later236}237238/*239* Wait for other side to close down.240*/241if (separateServerThread) {242serverThread.join();243} else {244clientThread.join();245}246247/*248* When we get here, the test is pretty much over.249* Which side threw the error?250*/251Exception local;252Exception remote;253String whichRemote;254255if (separateServerThread) {256remote = serverException;257local = clientException;258whichRemote = "server";259} else {260remote = clientException;261local = serverException;262whichRemote = "client";263}264265/*266* If both failed, return the curthread's exception, but also267* print the remote side Exception268*/269if ((local != null) && (remote != null)) {270System.out.println(whichRemote + " also threw:");271remote.printStackTrace();272System.out.println();273throw local;274}275276if (remote != null) {277throw remote;278}279280if (local != null) {281throw local;282}283}284285void startServer(boolean newThread) throws Exception {286if (newThread) {287serverThread = new Thread() {288public void run() {289try {290doServerSide();291} catch (Exception e) {292/*293* Our server thread just died.294*295* Release the client, if not active already...296*/297System.err.println("Server died...");298serverReady = true;299serverException = e;300}301}302};303serverThread.start();304} else {305try {306doServerSide();307} catch (Exception e) {308serverException = e;309} finally {310serverReady = true;311}312}313}314315void startClient(boolean newThread) throws Exception {316if (newThread) {317clientThread = new Thread() {318public void run() {319try {320doClientSide();321} catch (Exception e) {322/*323* Our client thread just died.324*/325System.err.println("Client died...");326clientException = e;327}328}329};330clientThread.start();331} else {332try {333doClientSide();334} catch (Exception e) {335clientException = e;336}337}338}339}340341342