Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/net/www/protocol/https/NewImpl/ComHostnameVerifier.java
38889 views
/*1* Copyright (c) 2001, 2018, 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// SunJSSE does not support dynamic system properties, no way to re-use24// system properties in samevm/agentvm mode.2526/*27* @test28* @bug 4474255 448424629* @summary When an application enables anonymous SSL cipher suite,30* Hostname verification is not required31* @run main/othervm ComHostnameVerifier32*/3334import java.io.*;35import java.net.*;36import java.security.Security;37import javax.net.ssl.*;38import javax.security.cert.*;39import com.sun.net.ssl.HostnameVerifier;40import com.sun.net.ssl.HttpsURLConnection;4142/**43* Use com.net.net.ssl.HostnameVerifier44*/45public class ComHostnameVerifier {4647/*48* =============================================================49* Set the various variables needed for the tests, then50* specify what tests to run on each side.51*/5253/*54* Should we run the client or server in a separate thread?55* Both sides can throw exceptions, but do you have a preference56* as to which side should be the main thread.57*/58static boolean separateServerThread = true;5960/*61* Is the server ready to serve?62*/63volatile static boolean serverReady = false;6465/*66* Turn on SSL debugging?67*/68static boolean debug = false;6970/*71* If the client or server is doing some kind of object creation72* that the other side depends on, and that thread prematurely73* exits, you may experience a hang. The test harness will74* terminate all hung threads after its timeout has expired,75* currently 3 minutes by default, but you might try to be76* smart about it....77*/7879/**80* Returns the path to the file obtained from81* parsing the HTML header.82*/83private static String getPath(DataInputStream in)84throws IOException85{86String line = in.readLine();87if (line == null)88return null;89String path = "";90// extract class from GET line91if (line.startsWith("GET /")) {92line = line.substring(5, line.length()-1).trim();93int index = line.indexOf(' ');94if (index != -1) {95path = line.substring(0, index);96}97}9899// eat the rest of header100do {101line = in.readLine();102} while ((line.length() != 0) &&103(line.charAt(0) != '\r') && (line.charAt(0) != '\n'));104105if (path.length() != 0) {106return path;107} else {108throw new IOException("Malformed Header");109}110}111112/**113* Returns an array of bytes containing the bytes for114* the file represented by the argument <b>path</b>.115*116* In our case, we just pretend to send something back.117*118* @return the bytes for the file119* @exception FileNotFoundException if the file corresponding120* to <b>path</b> could not be loaded.121*/122private byte[] getBytes(String path)123throws IOException124{125return "Hello world, I am here".getBytes();126}127128/*129* Define the server side of the test.130*131* If the server prematurely exits, serverReady will be set to true132* to avoid infinite hangs.133*/134void doServerSide() throws Exception {135136SSLServerSocketFactory sslssf =137(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();138SSLServerSocket sslServerSocket =139(SSLServerSocket) sslssf.createServerSocket(serverPort);140serverPort = sslServerSocket.getLocalPort();141142String ciphers[]= { "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA" };143sslServerSocket.setEnabledCipherSuites(ciphers);144145/*146* Signal Client, we're ready for his connect.147*/148serverReady = true;149150SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();151DataOutputStream out =152new DataOutputStream(sslSocket.getOutputStream());153154try {155// get path to class file from header156DataInputStream in =157new DataInputStream(sslSocket.getInputStream());158String path = getPath(in);159// retrieve bytecodes160byte[] bytecodes = getBytes(path);161// send bytecodes in response (assumes HTTP/1.0 or later)162try {163out.writeBytes("HTTP/1.0 200 OK\r\n");164out.writeBytes("Content-Length: " + bytecodes.length + "\r\n");165out.writeBytes("Content-Type: text/html\r\n\r\n");166out.write(bytecodes);167out.flush();168} catch (IOException ie) {169ie.printStackTrace();170return;171}172173} catch (Exception e) {174e.printStackTrace();175// write out error response176out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");177out.writeBytes("Content-Type: text/html\r\n\r\n");178out.flush();179} finally {180// close the socket181System.out.println("Server closing socket");182sslSocket.close();183serverReady = false;184}185}186187private static class ComSunHTTPSHandlerFactory implements URLStreamHandlerFactory {188private static String SUPPORTED_PROTOCOL = "https";189190public URLStreamHandler createURLStreamHandler(String protocol) {191if (!protocol.equalsIgnoreCase(SUPPORTED_PROTOCOL))192return null;193194return new com.sun.net.ssl.internal.www.protocol.https.Handler();195}196}197198/*199* Define the client side of the test.200*201* If the server prematurely exits, serverReady will be set to true202* to avoid infinite hangs.203*/204void doClientSide() throws Exception {205/*206* Wait for server to get started.207*/208while (!serverReady) {209Thread.sleep(50);210}211212URL.setURLStreamHandlerFactory(new ComSunHTTPSHandlerFactory());213214System.setProperty("https.cipherSuites",215"SSL_DH_anon_WITH_3DES_EDE_CBC_SHA");216217// use the default hostname verifier218219URL url = new URL("https://" + "localhost:" + serverPort +220"/etc/hosts");221URLConnection urlc = url.openConnection();222223if (!(urlc instanceof com.sun.net.ssl.HttpsURLConnection)) {224throw new Exception(225"URLConnection ! instanceof " +226"com.sun.net.ssl.HttpsURLConnection");227}228229BufferedReader in = null;230try {231in = new BufferedReader(new InputStreamReader(232urlc.getInputStream()));233String inputLine;234System.out.print("Client reading... ");235while ((inputLine = in.readLine()) != null)236System.out.println(inputLine);237System.out.println("Cipher Suite: " +238((HttpsURLConnection)urlc).getCipherSuite());239in.close();240} catch (SSLException e) {241if (in != null)242in.close();243throw e;244}245System.out.println("Client reports: SUCCESS");246}247248/*249* =============================================================250* The remainder is just support stuff251*/252253// use any free port by default254volatile int serverPort = 0;255256volatile Exception serverException = null;257volatile Exception clientException = null;258259public static void main(String[] args) throws Exception {260// re-enable 3DES261Security.setProperty("jdk.tls.disabledAlgorithms", "");262263if (debug)264System.setProperty("javax.net.debug", "all");265266/*267* Start the tests.268*/269new ComHostnameVerifier();270}271272Thread clientThread = null;273Thread serverThread = null;274275/*276* Primary constructor, used to drive remainder of the test.277*278* Fork off the other side, then do your work.279*/280ComHostnameVerifier() throws Exception {281if (separateServerThread) {282startServer(true);283startClient(false);284} else {285startClient(true);286startServer(false);287}288289/*290* Wait for other side to close down.291*/292if (separateServerThread) {293serverThread.join();294} else {295clientThread.join();296}297298/*299* When we get here, the test is pretty much over.300*301* If the main thread excepted, that propagates back302* immediately. If the other thread threw an exception, we303* should report back.304*/305if (serverException != null) {306System.out.print("Server Exception:");307throw serverException;308}309if (clientException != null) {310System.out.print("Client Exception:");311throw clientException;312}313}314315void startServer(boolean newThread) throws Exception {316if (newThread) {317serverThread = new Thread() {318public void run() {319try {320doServerSide();321} catch (Exception e) {322/*323* Our server thread just died.324*325* Release the client, if not active already...326*/327System.err.println("Server died...");328serverReady = true;329serverException = e;330}331}332};333serverThread.start();334} else {335doServerSide();336}337}338339void startClient(boolean newThread) throws Exception {340if (newThread) {341clientThread = new Thread() {342public void run() {343try {344doClientSide();345} catch (Exception e) {346/*347* Our client thread just died.348*/349System.err.println("Client died...");350clientException = e;351}352}353};354clientThread.start();355} else {356doClientSide();357}358}359}360361362