Path: blob/master/test/jdk/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java
41152 views
/*1* Copyright (c) 2015, 2016, 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 718865731* @summary There should be a way to reorder the JSSE ciphers32* @run main/othervm UseCipherSuitesOrder33* TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA34*/3536import java.io.*;37import java.security.Security;38import javax.net.ssl.*;39import java.util.Arrays;4041public class UseCipherSuitesOrder {4243/*44* =============================================================45* Set the various variables needed for the tests, then46* specify what tests to run on each side.47*/4849/*50* Should we run the client or server in a separate thread?51* Both sides can throw exceptions, but do you have a preference52* as to which side should be the main thread.53*/54static boolean separateServerThread = false;5556/*57* Where do we find the keystores?58*/59static String pathToStores = "../etc";60static String keyStoreFile = "keystore";61static String trustStoreFile = "truststore";62static String passwd = "passphrase";6364/*65* Is the server ready to serve?66*/67volatile static boolean serverReady = false;6869/*70* Turn on SSL debugging?71*/72static boolean debug = false;7374/*75* If the client or server is doing some kind of object creation76* that the other side depends on, and that thread prematurely77* exits, you may experience a hang. The test harness will78* terminate all hung threads after its timeout has expired,79* currently 3 minutes by default, but you might try to be80* smart about it....81*/8283/*84* Define the server side of the test.85*86* If the server prematurely exits, serverReady will be set to true87* to avoid infinite hangs.88*/89void doServerSide() throws Exception {90SSLServerSocketFactory sslssf =91(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();92SSLServerSocket sslServerSocket =93(SSLServerSocket) sslssf.createServerSocket(serverPort);94serverPort = sslServerSocket.getLocalPort();9596// use local cipher suites preference97SSLParameters params = sslServerSocket.getSSLParameters();98params.setUseCipherSuitesOrder(true);99params.setCipherSuites(srvEnabledCipherSuites);100sslServerSocket.setSSLParameters(params);101102/*103* Signal Client, we're ready for his connect.104*/105serverReady = true;106107SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();108InputStream sslIS = sslSocket.getInputStream();109OutputStream sslOS = sslSocket.getOutputStream();110111sslIS.read();112sslOS.write(85);113sslOS.flush();114115SSLSession session = sslSocket.getSession();116if (!srvEnabledCipherSuites[0].equals(session.getCipherSuite())) {117throw new Exception(118"Expected to negotiate " + srvEnabledCipherSuites[0] +119" , but not " + session.getCipherSuite());120}121122sslSocket.close();123}124125/*126* Define the client side of the test.127*128* If the server prematurely exits, serverReady will be set to true129* to avoid infinite hangs.130*/131void doClientSide() throws Exception {132133/*134* Wait for server to get started.135*/136while (!serverReady) {137Thread.sleep(50);138}139140SSLSocketFactory sslsf =141(SSLSocketFactory) SSLSocketFactory.getDefault();142SSLSocket sslSocket = (SSLSocket)143sslsf.createSocket("localhost", serverPort);144sslSocket.setEnabledCipherSuites(cliEnabledCipherSuites);145146InputStream sslIS = sslSocket.getInputStream();147OutputStream sslOS = sslSocket.getOutputStream();148149sslOS.write(280);150sslOS.flush();151sslIS.read();152153sslSocket.close();154}155156// client enabled cipher suites157private static String[] cliEnabledCipherSuites;158159// server enabled cipher suites160private static String[] srvEnabledCipherSuites;161162private static void parseArguments(String[] args) throws Exception {163if (args.length != 1) {164System.out.println("Usage: java UseCipherSuitesOrder ciphersuites");165System.out.println("\tciphersuites: " +166"a list of enabled cipher suites, separated with comma");167throw new Exception("Incorrect usage");168}169170cliEnabledCipherSuites = args[0].split(",");171172if (cliEnabledCipherSuites.length < 2) {173throw new Exception("Need to enable at least two cipher suites");174}175176// Only need to use 2 cipher suites in server side.177srvEnabledCipherSuites = Arrays.<String>copyOf(178cliEnabledCipherSuites, 2);179180// Reverse the cipher suite preference in server side.181srvEnabledCipherSuites[0] = cliEnabledCipherSuites[1];182srvEnabledCipherSuites[1] = cliEnabledCipherSuites[0];183}184185/*186* =============================================================187* The remainder is just support stuff188*/189190// use any free port by default191volatile int serverPort = 0;192193volatile Exception serverException = null;194volatile Exception clientException = null;195196public static void main(String[] args) throws Exception {197// reset the security property to make sure that the algorithms198// and keys used in this test are not disabled.199Security.setProperty("jdk.tls.disabledAlgorithms", "");200201// parse the arguments202parseArguments(args);203204String keyFilename =205System.getProperty("test.src", ".") + "/" + pathToStores +206"/" + keyStoreFile;207String trustFilename =208System.getProperty("test.src", ".") + "/" + pathToStores +209"/" + trustStoreFile;210211System.setProperty("javax.net.ssl.keyStore", keyFilename);212System.setProperty("javax.net.ssl.keyStorePassword", passwd);213System.setProperty("javax.net.ssl.trustStore", trustFilename);214System.setProperty("javax.net.ssl.trustStorePassword", passwd);215216if (debug)217System.setProperty("javax.net.debug", "all");218219/*220* Start the tests.221*/222new UseCipherSuitesOrder();223}224225Thread clientThread = null;226Thread serverThread = null;227228/*229* Primary constructor, used to drive remainder of the test.230*231* Fork off the other side, then do your work.232*/233UseCipherSuitesOrder() throws Exception {234Exception startException = null;235try {236if (separateServerThread) {237startServer(true);238startClient(false);239} else {240startClient(true);241startServer(false);242}243} catch (Exception e) {244startException = e;245}246247/*248* Wait for other side to close down.249*/250if (separateServerThread) {251if (serverThread != null) {252serverThread.join();253}254} else {255if (clientThread != null) {256clientThread.join();257}258}259260/*261* When we get here, the test is pretty much over.262* Which side threw the error?263*/264Exception local;265Exception remote;266267if (separateServerThread) {268remote = serverException;269local = clientException;270} else {271remote = clientException;272local = serverException;273}274275Exception exception = null;276277/*278* Check various exception conditions.279*/280if ((local != null) && (remote != null)) {281// If both failed, return the curthread's exception.282local.initCause(remote);283exception = local;284} else if (local != null) {285exception = local;286} else if (remote != null) {287exception = remote;288} else if (startException != null) {289exception = startException;290}291292/*293* If there was an exception *AND* a startException,294* output it.295*/296if (exception != null) {297if (exception != startException && startException != null) {298exception.addSuppressed(startException);299}300throw exception;301}302303// Fall-through: no exception to throw!304}305306void startServer(boolean newThread) throws Exception {307if (newThread) {308serverThread = new Thread() {309public void run() {310try {311doServerSide();312} catch (Exception e) {313/*314* Our server thread just died.315*316* Release the client, if not active already...317*/318System.err.println("Server died...");319serverReady = true;320serverException = e;321}322}323};324serverThread.start();325} else {326try {327doServerSide();328} catch (Exception e) {329serverException = e;330} finally {331serverReady = true;332}333}334}335336void startClient(boolean newThread) throws Exception {337if (newThread) {338clientThread = new Thread() {339public void run() {340try {341doClientSide();342} catch (Exception e) {343/*344* Our client thread just died.345*/346System.err.println("Client died...");347clientException = e;348}349}350};351clientThread.start();352} else {353try {354doClientSide();355} catch (Exception e) {356clientException = e;357}358}359}360}361362363