Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorer.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 ../SSLEngine ../templates33* @build SSLEngineService SSLCapabilities SSLExplorer34* @run main/othervm SSLEngineExplorer SSLv2Hello,SSLv335* @run main/othervm SSLEngineExplorer SSLv336* @run main/othervm SSLEngineExplorer TLSv137* @run main/othervm SSLEngineExplorer TLSv1.138* @run main/othervm SSLEngineExplorer TLSv1.239*/4041import javax.net.ssl.*;42import java.nio.*;43import java.net.*;44import java.util.*;45import java.nio.channels.*;46import java.security.Security;4748public class SSLEngineExplorer extends SSLEngineService {4950/*51* =============================================================52* Set the various variables needed for the tests, then53* specify what tests to run on each side.54*/5556/*57* Should we run the client or server in a separate thread?58* Both sides can throw exceptions, but do you have a preference59* as to which side should be the main thread.60*/61static boolean separateServerThread = true;6263// Is the server ready to serve?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 {7879// create SSLEngine.80SSLEngine ssle = createSSLEngine(false);8182// Create a server socket channel.83InetSocketAddress isa =84new InetSocketAddress(InetAddress.getLocalHost(), serverPort);85ServerSocketChannel ssc = ServerSocketChannel.open();86ssc.socket().bind(isa);87serverPort = ssc.socket().getLocalPort();8889// Signal Client, we're ready for his connect.90serverReady = true;9192// Accept a socket channel.93SocketChannel sc = ssc.accept();94sc.configureBlocking(false);9596// Complete connection.97while (!sc.finishConnect()) {98Thread.sleep(50);99// waiting for the connection completed.100}101102ByteBuffer buffer = ByteBuffer.allocate(0xFF);103int position = 0;104SSLCapabilities capabilities = null;105106// Read the header of TLS record107buffer.limit(SSLExplorer.RECORD_HEADER_SIZE);108while (position < SSLExplorer.RECORD_HEADER_SIZE) {109int n = sc.read(buffer);110if (n < 0) {111throw new Exception("unexpected end of stream!");112}113position += n;114}115buffer.flip();116117int recordLength = SSLExplorer.getRequiredSize(buffer);118if (buffer.capacity() < recordLength) {119ByteBuffer oldBuffer = buffer;120buffer = ByteBuffer.allocate(recordLength);121buffer.put(oldBuffer);122}123124buffer.position(SSLExplorer.RECORD_HEADER_SIZE);125buffer.limit(buffer.capacity());126while (position < recordLength) {127int n = sc.read(buffer);128if (n < 0) {129throw new Exception("unexpected end of stream!");130}131position += n;132}133buffer.flip();134135capabilities = SSLExplorer.explore(buffer);136if (capabilities != null) {137System.out.println("Record version: " +138capabilities.getRecordVersion());139System.out.println("Hello version: " +140capabilities.getHelloVersion());141}142143// handshaking144handshaking(ssle, sc, buffer);145146// receive application data147receive(ssle, sc);148149// send out application data150deliver(ssle, sc);151152ExtendedSSLSession session = (ExtendedSSLSession)ssle.getSession();153checkCapabilities(capabilities, session);154155// close the socket channel.156sc.close();157ssc.close();158}159160/*161* Define the client side of the test.162*163* If the server prematurely exits, serverReady will be set to true164* to avoid infinite hangs.165*/166void doClientSide() throws Exception {167// create SSLEngine.168SSLEngine ssle = createSSLEngine(true);169170/*171* Wait for server to get started.172*/173while (!serverReady) {174Thread.sleep(50);175}176177// Create a non-blocking socket channel.178SocketChannel sc = SocketChannel.open();179sc.configureBlocking(false);180InetSocketAddress isa =181new InetSocketAddress(InetAddress.getLocalHost(), serverPort);182sc.connect(isa);183184// Complete connection.185while (!sc.finishConnect() ) {186Thread.sleep(50);187// waiting for the connection completed.188}189190// enable the specified TLS protocol191ssle.setEnabledProtocols(supportedProtocols);192193// handshaking194handshaking(ssle, sc, null);195196// send out application data197deliver(ssle, sc);198199// receive application data200receive(ssle, sc);201202// close the socket channel.203sc.close();204}205206void checkCapabilities(SSLCapabilities capabilities,207ExtendedSSLSession session) throws Exception {208209List<SNIServerName> sessionSNI = session.getRequestedServerNames();210if (!sessionSNI.equals(capabilities.getServerNames())) {211throw new Exception(212"server name indication does not match capabilities");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*/227volatile Exception serverException = null;228volatile Exception clientException = null;229230// use any free port by default231volatile int serverPort = 0;232233public static void main(String args[]) throws Exception {234// reset the security property to make sure that the algorithms235// and keys used in this test are not disabled.236Security.setProperty("jdk.tls.disabledAlgorithms", "");237238if (debug)239System.setProperty("javax.net.debug", "all");240241/*242* Get the customized arguments.243*/244parseArguments(args);245246new SSLEngineExplorer();247}248249Thread clientThread = null;250Thread serverThread = null;251252/*253* Primary constructor, used to drive remainder of the test.254*255* Fork off the other side, then do your work.256*/257SSLEngineExplorer() throws Exception {258super("../etc");259260if (separateServerThread) {261startServer(true);262startClient(false);263} else {264startClient(true);265startServer(false);266}267268/*269* Wait for other side to close down.270*/271if (separateServerThread) {272serverThread.join();273} else {274clientThread.join();275}276277/*278* When we get here, the test is pretty much over.279*280* If the main thread excepted, that propagates back281* immediately. If the other thread threw an exception, we282* should report back.283*/284if (serverException != null) {285System.out.print("Server Exception:");286throw serverException;287}288if (clientException != null) {289System.out.print("Client Exception:");290throw clientException;291}292}293294void startServer(boolean newThread) throws Exception {295if (newThread) {296serverThread = new Thread() {297public void run() {298try {299doServerSide();300} catch (Exception e) {301/*302* Our server thread just died.303*304* Release the client, if not active already...305*/306System.err.println("Server died...");307System.err.println(e);308serverReady = true;309serverException = e;310}311}312};313serverThread.start();314} else {315doServerSide();316}317}318319void startClient(boolean newThread) throws Exception {320if (newThread) {321clientThread = new Thread() {322public void run() {323try {324doClientSide();325} catch (Exception e) {326/*327* Our client thread just died.328*/329System.err.println("Client died...");330clientException = e;331}332}333};334clientThread.start();335} else {336doClientSide();337}338}339}340341342