Path: blob/master/test/jdk/sun/security/ssl/X509TrustManagerImpl/CertRequestOverflow.java
41152 views
/*1* Copyright (c) 2012, 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//24// SunJSSE does not support dynamic system properties, no way to re-use25// system properties in samevm/agentvm mode.26//2728/*29* @test30* @bug 720029531* @summary CertificateRequest message is wrapping when using large32* numbers of Certs33* @run main/othervm CertRequestOverflow34*/3536import java.io.*;37import java.net.*;38import java.util.*;39import javax.net.ssl.*;40import java.security.cert.*;41import java.security.*;4243public class CertRequestOverflow {4445/*46* =============================================================47* Set the various variables needed for the tests, then48* specify what tests to run on each side.49*/5051/*52* Should we run the client or server in a separate thread?53* Both sides can throw exceptions, but do you have a preference54* as to which side should be the main thread.55*/56static boolean separateServerThread = false;5758/*59* Where do we find the keystores?60*/61static String pathToStores = "../../../../javax/net/ssl/etc";62static String keyStoreFile = "keystore";63static String trustStoreFile = "truststore";64static String passwd = "passphrase";65private final static char[] cpasswd = "passphrase".toCharArray();6667/*68* Is the server ready to serve?69*/70volatile static boolean serverReady = false;7172/*73* Turn on SSL debugging?74*/75static boolean debug = false;7677/*78* If the client or server is doing some kind of object creation79* that the other side depends on, and that thread prematurely80* exits, you may experience a hang. The test harness will81* terminate all hung threads after its timeout has expired,82* currently 3 minutes by default, but you might try to be83* smart about it....84*/8586/*87* Define the server side of the test.88*89* If the server prematurely exits, serverReady will be set to true90* to avoid infinite hangs.91*/92void doServerSide() throws Exception {93SSLServerSocketFactory sslssf =94getContext(true).getServerSocketFactory();95SSLServerSocket sslServerSocket =96(SSLServerSocket) sslssf.createServerSocket(serverPort);97serverPort = sslServerSocket.getLocalPort();98if (debug) {99System.out.println("Server port is " + serverPort);100}101102// enable endpoint identification103// ignore, we may test the feature when known how to parse client104// hostname105//SSLParameters params = sslServerSocket.getSSLParameters();106//params.setEndpointIdentificationAlgorithm("HTTPS");107//sslServerSocket.setSSLParameters(params);108109/*110* Signal Client, we're ready for his connect.111*/112serverReady = true;113114SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();115sslSocket.setNeedClientAuth(true);116InputStream sslIS = sslSocket.getInputStream();117OutputStream sslOS = sslSocket.getOutputStream();118119try {120sslIS.read();121sslOS.write(85);122sslOS.flush();123124throw new Exception("SERVER TEST FAILED! " +125"It is expected to fail with field length overflow");126} catch (SSLException ssle) {127Throwable cause = ssle.getCause();128if (!(cause instanceof RuntimeException)) {129System.out.println("We are expecting a RuntimeException!");130throw ssle;131}132System.out.println("The expected exception! " + ssle);133} finally {134sslSocket.close();135}136137System.out.println("SERVER TEST PASSED!");138}139140/*141* Define the client side of the test.142*143* If the server prematurely exits, serverReady will be set to true144* to avoid infinite hangs.145*/146void doClientSide() throws Exception {147148/*149* Wait for server to get started.150*/151while (!serverReady) {152Thread.sleep(50);153}154155SSLSocketFactory sslsf = getContext(false).getSocketFactory();156SSLSocket sslSocket = (SSLSocket)157sslsf.createSocket("localhost", serverPort);158if (debug) {159System.out.println("Connected to: " +160sslSocket.getRemoteSocketAddress());161}162163// enable endpoint identification164SSLParameters params = sslSocket.getSSLParameters();165params.setEndpointIdentificationAlgorithm("HTTPS");166sslSocket.setSSLParameters(params);167168InputStream sslIS = sslSocket.getInputStream();169OutputStream sslOS = sslSocket.getOutputStream();170171try {172sslOS.write(280);173sslOS.flush();174sslIS.read();175} catch (SSLException ssle) {176System.out.println("An expected exception!");177} finally {178sslSocket.close();179}180}181182MyExtendedX509TM serverTM;183MyExtendedX509TM clientTM;184185private SSLContext getContext(boolean server) throws Exception {186String keyFilename =187System.getProperty("test.src", "./") + "/" + pathToStores +188"/" + keyStoreFile;189String trustFilename =190System.getProperty("test.src", "./") + "/" + pathToStores +191"/" + trustStoreFile;192193KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");194KeyStore ks = KeyStore.getInstance("JKS");195ks.load(new FileInputStream(keyFilename), cpasswd);196kmf.init(ks, cpasswd);197198TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");199KeyStore ts = KeyStore.getInstance("JKS");200ts.load(new FileInputStream(trustFilename), cpasswd);201tmf.init(ts);202203TrustManager tms[] = tmf.getTrustManagers();204if (tms == null || tms.length == 0) {205throw new Exception("unexpected trust manager implementation");206} else {207if (!(tms[0] instanceof X509TrustManager)) {208throw new Exception("unexpected trust manager implementation: "209+ tms[0].getClass().getCanonicalName());210}211}212213if (server) {214serverTM = new MyExtendedX509TM((X509TrustManager)tms[0]);215216tms = new TrustManager[] {serverTM};217} else {218clientTM = new MyExtendedX509TM((X509TrustManager)tms[0]);219220tms = new TrustManager[] {clientTM};221}222223SSLContext ctx = SSLContext.getInstance("TLSv1.2");224ctx.init(kmf.getKeyManagers(), tms, null);225226return ctx;227}228229static class MyExtendedX509TM extends X509ExtendedTrustManager230implements X509TrustManager {231232X509TrustManager tm;233234boolean clientChecked;235boolean serverChecked;236237MyExtendedX509TM(X509TrustManager tm) {238clientChecked = false;239serverChecked = false;240241this.tm = tm;242}243244public boolean wasClientChecked() {245return clientChecked;246}247248public boolean wasServerChecked() {249return serverChecked;250}251252@Override253public void checkClientTrusted(X509Certificate chain[], String authType)254throws CertificateException {255tm.checkClientTrusted(chain, authType);256}257258@Override259public void checkServerTrusted(X509Certificate chain[], String authType)260throws CertificateException {261tm.checkServerTrusted(chain, authType);262}263264@Override265public X509Certificate[] getAcceptedIssuers() {266// (hack code) increase the size of the returned array to make a267// overflow CertificateRequest.268List<X509Certificate> issuersList = new LinkedList<>();269X509Certificate[] issuers = tm.getAcceptedIssuers();270for (int i = 0; i < 800; i += issuers.length) {271for (X509Certificate issuer : issuers) {272issuersList.add(issuer);273}274}275276return issuersList.toArray(issuers);277}278279@Override280public void checkClientTrusted(X509Certificate[] chain, String authType,281Socket socket) throws CertificateException {282clientChecked = true;283tm.checkClientTrusted(chain, authType);284}285286@Override287public void checkServerTrusted(X509Certificate[] chain, String authType,288Socket socket) throws CertificateException {289serverChecked = true;290tm.checkServerTrusted(chain, authType);291}292293@Override294public void checkClientTrusted(X509Certificate[] chain, String authType,295SSLEngine engine) throws CertificateException {296clientChecked = true;297tm.checkClientTrusted(chain, authType);298}299300@Override301public void checkServerTrusted(X509Certificate[] chain, String authType,302SSLEngine engine) throws CertificateException {303serverChecked = true;304tm.checkServerTrusted(chain, authType);305}306}307308/*309* =============================================================310* The remainder is just support stuff311*/312313// use any free port by default314volatile int serverPort = 0;315316volatile Exception serverException = null;317volatile Exception clientException = null;318319public static void main(String[] args) throws Exception {320321if (debug)322System.setProperty("javax.net.debug", "all");323324/*325* Start the tests.326*/327new CertRequestOverflow();328}329330Thread clientThread = null;331Thread serverThread = null;332333/*334* Primary constructor, used to drive remainder of the test.335*336* Fork off the other side, then do your work.337*/338CertRequestOverflow() throws Exception {339if (separateServerThread) {340startServer(true);341startClient(false);342} else {343startClient(true);344startServer(false);345}346347/*348* Wait for other side to close down.349*/350if (separateServerThread) {351serverThread.join();352} else {353clientThread.join();354}355356/*357* When we get here, the test is pretty much over.358*359* If the main thread excepted, that propagates back360* immediately. If the other thread threw an exception, we361* should report back.362*/363if (serverException != null)364throw serverException;365if (clientException != null)366throw clientException;367}368369void startServer(boolean newThread) throws Exception {370if (newThread) {371serverThread = new Thread() {372@Override373public void run() {374try {375doServerSide();376} catch (Exception e) {377/*378* Our server thread just died.379*380* Release the client, if not active already...381*/382System.err.println("Server died...");383serverReady = true;384serverException = e;385}386}387};388serverThread.start();389} else {390doServerSide();391}392}393394void startClient(boolean newThread) throws Exception {395if (newThread) {396clientThread = new Thread() {397@Override398public void run() {399try {400doClientSide();401} catch (Exception e) {402/*403* Our client thread just died.404*/405System.err.println("Client died...");406clientException = e;407}408}409};410clientThread.start();411} else {412doClientSide();413}414}415}416417418419