Path: blob/master/test/jdk/javax/net/ssl/ServerName/SSLEngineExplorer.java
41152 views
/*1* Copyright (c) 2012, 2019, 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 7068321 819049231* @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// Enable all supported protocols on server side to test SSLv383ssle.setEnabledProtocols(ssle.getSupportedProtocols());8485// Create a server socket channel.86InetSocketAddress isa =87new InetSocketAddress(InetAddress.getLocalHost(), serverPort);88ServerSocketChannel ssc = ServerSocketChannel.open();89ssc.socket().bind(isa);90serverPort = ssc.socket().getLocalPort();9192// Signal Client, we're ready for his connect.93serverReady = true;9495// Accept a socket channel.96SocketChannel sc = ssc.accept();97sc.configureBlocking(false);9899// Complete connection.100while (!sc.finishConnect()) {101Thread.sleep(50);102// waiting for the connection completed.103}104105ByteBuffer buffer = ByteBuffer.allocate(0xFF);106int position = 0;107SSLCapabilities capabilities = null;108109// Read the header of TLS record110buffer.limit(SSLExplorer.RECORD_HEADER_SIZE);111while (position < SSLExplorer.RECORD_HEADER_SIZE) {112int n = sc.read(buffer);113if (n < 0) {114throw new Exception("unexpected end of stream!");115}116position += n;117}118buffer.flip();119120int recordLength = SSLExplorer.getRequiredSize(buffer);121if (buffer.capacity() < recordLength) {122ByteBuffer oldBuffer = buffer;123buffer = ByteBuffer.allocate(recordLength);124buffer.put(oldBuffer);125}126127buffer.position(SSLExplorer.RECORD_HEADER_SIZE);128buffer.limit(buffer.capacity());129while (position < recordLength) {130int n = sc.read(buffer);131if (n < 0) {132throw new Exception("unexpected end of stream!");133}134position += n;135}136buffer.flip();137138capabilities = SSLExplorer.explore(buffer);139if (capabilities != null) {140System.out.println("Record version: " +141capabilities.getRecordVersion());142System.out.println("Hello version: " +143capabilities.getHelloVersion());144}145146// handshaking147handshaking(ssle, sc, buffer);148149// receive application data150receive(ssle, sc);151152// send out application data153deliver(ssle, sc);154155ExtendedSSLSession session = (ExtendedSSLSession)ssle.getSession();156checkCapabilities(capabilities, session);157158// close the socket channel.159sc.close();160ssc.close();161}162163/*164* Define the client side of the test.165*166* If the server prematurely exits, serverReady will be set to true167* to avoid infinite hangs.168*/169void doClientSide() throws Exception {170// create SSLEngine.171SSLEngine ssle = createSSLEngine(true);172173/*174* Wait for server to get started.175*/176while (!serverReady) {177Thread.sleep(50);178}179180// Create a non-blocking socket channel.181SocketChannel sc = SocketChannel.open();182sc.configureBlocking(false);183InetSocketAddress isa =184new InetSocketAddress(InetAddress.getLocalHost(), serverPort);185sc.connect(isa);186187// Complete connection.188while (!sc.finishConnect() ) {189Thread.sleep(50);190// waiting for the connection completed.191}192193// enable the specified TLS protocol194ssle.setEnabledProtocols(supportedProtocols);195196// handshaking197handshaking(ssle, sc, null);198199// send out application data200deliver(ssle, sc);201202// receive application data203receive(ssle, sc);204205// close the socket channel.206sc.close();207}208209void checkCapabilities(SSLCapabilities capabilities,210ExtendedSSLSession session) throws Exception {211212List<SNIServerName> sessionSNI = session.getRequestedServerNames();213if (!sessionSNI.equals(capabilities.getServerNames())) {214throw new Exception(215"server name indication does not match capabilities");216}217}218219private static String[] supportedProtocols; // supported protocols220221private static void parseArguments(String[] args) {222supportedProtocols = args[0].split(",");223}224225226/*227* =============================================================228* The remainder is just support stuff229*/230volatile Exception serverException = null;231volatile Exception clientException = null;232233// use any free port by default234volatile int serverPort = 0;235236public static void main(String args[]) throws Exception {237// reset the security property to make sure that the algorithms238// and keys used in this test are not disabled.239Security.setProperty("jdk.tls.disabledAlgorithms", "");240241if (debug)242System.setProperty("javax.net.debug", "all");243244/*245* Get the customized arguments.246*/247parseArguments(args);248249new SSLEngineExplorer();250}251252Thread clientThread = null;253Thread serverThread = null;254255/*256* Primary constructor, used to drive remainder of the test.257*258* Fork off the other side, then do your work.259*/260SSLEngineExplorer() throws Exception {261super("../etc");262263if (separateServerThread) {264startServer(true);265startClient(false);266} else {267startClient(true);268startServer(false);269}270271/*272* Wait for other side to close down.273*/274if (separateServerThread) {275serverThread.join();276} else {277clientThread.join();278}279280/*281* When we get here, the test is pretty much over.282*283* If the main thread excepted, that propagates back284* immediately. If the other thread threw an exception, we285* should report back.286*/287if (serverException != null) {288System.out.print("Server Exception:");289throw serverException;290}291if (clientException != null) {292System.out.print("Client Exception:");293throw clientException;294}295}296297void startServer(boolean newThread) throws Exception {298if (newThread) {299serverThread = new Thread() {300public void run() {301try {302doServerSide();303} catch (Exception e) {304/*305* Our server thread just died.306*307* Release the client, if not active already...308*/309System.err.println("Server died...");310System.err.println(e);311serverReady = true;312serverException = e;313}314}315};316serverThread.start();317} else {318doServerSide();319}320}321322void startClient(boolean newThread) throws Exception {323if (newThread) {324clientThread = new Thread() {325public void run() {326try {327doClientSide();328} catch (Exception e) {329/*330* Our client thread just died.331*/332System.err.println("Client died...");333clientException = e;334}335}336};337clientThread.start();338} else {339doClientSide();340}341}342}343344345