Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorer.java
38853 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 SSLSocketExplorer SSLv2Hello,SSLv335* @run main/othervm SSLSocketExplorer SSLv336* @run main/othervm SSLSocketExplorer TLSv137* @run main/othervm SSLSocketExplorer TLSv1.138* @run main/othervm SSLSocketExplorer 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 SSLSocketExplorer {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;111112// Read the header of TLS record113while (position < SSLExplorer.RECORD_HEADER_SIZE) {114int count = SSLExplorer.RECORD_HEADER_SIZE - position;115int n = ins.read(buffer, position, count);116if (n < 0) {117throw new Exception("unexpected end of stream!");118}119position += n;120}121122int recordLength = SSLExplorer.getRequiredSize(buffer, 0, position);123if (buffer.length < recordLength) {124buffer = Arrays.copyOf(buffer, recordLength);125}126127while (position < recordLength) {128int count = recordLength - position;129int n = ins.read(buffer, position, count);130if (n < 0) {131throw new Exception("unexpected end of stream!");132}133position += n;134}135136capabilities = SSLExplorer.explore(buffer, 0, recordLength);;137if (capabilities != null) {138System.out.println("Record version: " +139capabilities.getRecordVersion());140System.out.println("Hello version: " +141capabilities.getHelloVersion());142}143144SSLSocketFactory sslsf =145(SSLSocketFactory) SSLSocketFactory.getDefault();146ByteArrayInputStream bais =147new ByteArrayInputStream(buffer, 0, position);148SSLSocket sslSocket = (SSLSocket)sslsf.createSocket(socket, bais, true);149150InputStream sslIS = sslSocket.getInputStream();151OutputStream sslOS = sslSocket.getOutputStream();152153sslIS.read();154sslOS.write(85);155sslOS.flush();156157ExtendedSSLSession session = (ExtendedSSLSession)sslSocket.getSession();158checkCapabilities(capabilities, session);159160sslSocket.close();161serverSocket.close();162}163164165/*166* Define the client side of the test.167*168* If the server prematurely exits, serverReady will be set to true169* to avoid infinite hangs.170*/171void doClientSide() throws Exception {172173/*174* Wait for server to get started.175*/176while (!serverReady) {177Thread.sleep(50);178}179180SSLSocketFactory sslsf =181(SSLSocketFactory) SSLSocketFactory.getDefault();182SSLSocket sslSocket = (SSLSocket)183sslsf.createSocket("localhost", serverPort);184185// enable the specified TLS protocol186sslSocket.setEnabledProtocols(supportedProtocols);187188InputStream sslIS = sslSocket.getInputStream();189OutputStream sslOS = sslSocket.getOutputStream();190191sslOS.write(280);192sslOS.flush();193sslIS.read();194195sslSocket.close();196}197198void checkCapabilities(SSLCapabilities capabilities,199ExtendedSSLSession session) throws Exception {200201List<SNIServerName> sessionSNI = session.getRequestedServerNames();202if (!sessionSNI.equals(capabilities.getServerNames())) {203throw new Exception(204"server name indication does not match capabilities");205}206}207208private static String[] supportedProtocols; // supported protocols209210private static void parseArguments(String[] args) {211supportedProtocols = args[0].split(",");212}213214215/*216* =============================================================217* The remainder is just support stuff218*/219220// use any free port by default221volatile int serverPort = 0;222223volatile Exception serverException = null;224volatile Exception clientException = null;225226public static void main(String[] args) throws Exception {227// reset the security property to make sure that the algorithms228// and keys used in this test are not disabled.229Security.setProperty("jdk.tls.disabledAlgorithms", "");230231String keyFilename =232System.getProperty("test.src", ".") + "/" + pathToStores +233"/" + keyStoreFile;234String trustFilename =235System.getProperty("test.src", ".") + "/" + pathToStores +236"/" + trustStoreFile;237238System.setProperty("javax.net.ssl.keyStore", keyFilename);239System.setProperty("javax.net.ssl.keyStorePassword", passwd);240System.setProperty("javax.net.ssl.trustStore", trustFilename);241System.setProperty("javax.net.ssl.trustStorePassword", passwd);242243if (debug)244System.setProperty("javax.net.debug", "all");245246/*247* Get the customized arguments.248*/249parseArguments(args);250251/*252* Start the tests.253*/254new SSLSocketExplorer();255}256257Thread clientThread = null;258Thread serverThread = null;259260/*261* Primary constructor, used to drive remainder of the test.262*263* Fork off the other side, then do your work.264*/265SSLSocketExplorer() throws Exception {266try {267if (separateServerThread) {268startServer(true);269startClient(false);270} else {271startClient(true);272startServer(false);273}274} catch (Exception e) {275// swallow for now. Show later276}277278/*279* Wait for other side to close down.280*/281if (separateServerThread) {282serverThread.join();283} else {284clientThread.join();285}286287/*288* When we get here, the test is pretty much over.289* Which side threw the error?290*/291Exception local;292Exception remote;293String whichRemote;294295if (separateServerThread) {296remote = serverException;297local = clientException;298whichRemote = "server";299} else {300remote = clientException;301local = serverException;302whichRemote = "client";303}304305/*306* If both failed, return the curthread's exception, but also307* print the remote side Exception308*/309if ((local != null) && (remote != null)) {310System.out.println(whichRemote + " also threw:");311remote.printStackTrace();312System.out.println();313throw local;314}315316if (remote != null) {317throw remote;318}319320if (local != null) {321throw local;322}323}324325void startServer(boolean newThread) throws Exception {326if (newThread) {327serverThread = new Thread() {328public void run() {329try {330doServerSide();331} catch (Exception e) {332/*333* Our server thread just died.334*335* Release the client, if not active already...336*/337System.err.println("Server died...");338serverReady = true;339serverException = e;340}341}342};343serverThread.start();344} else {345try {346doServerSide();347} catch (Exception e) {348serverException = e;349} finally {350serverReady = true;351}352}353}354355void startClient(boolean newThread) throws Exception {356if (newThread) {357clientThread = new Thread() {358public void run() {359try {360doClientSide();361} catch (Exception e) {362/*363* Our client thread just died.364*/365System.err.println("Client died...");366clientException = e;367}368}369};370clientThread.start();371} else {372try {373doClientSide();374} catch (Exception e) {375clientException = e;376}377}378}379}380381382