jdk/test/javax/net/ssl/TLSv11/EmptyCertificateAuthorities.java
changeset 23052 241885315119
parent 22268 d72c97c708ae
child 35298 9f93cbce8c44
equal deleted inserted replaced
23051:501d8479f798 23052:241885315119
       
     1 /*
       
     2  * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 //
       
    27 // SunJSSE does not support dynamic system properties, no way to re-use
       
    28 // system properties in samevm/agentvm mode.
       
    29 //
       
    30 
       
    31 /*
       
    32  * @test
       
    33  * @bug 4873188
       
    34  * @summary Support TLS 1.1
       
    35  * @run main/othervm EmptyCertificateAuthorities
       
    36  * @author Xuelei Fan
       
    37  */
       
    38 
       
    39 import java.io.*;
       
    40 import java.net.*;
       
    41 import java.security.*;
       
    42 import java.security.cert.*;
       
    43 import javax.net.ssl.*;
       
    44 
       
    45 public class EmptyCertificateAuthorities {
       
    46 
       
    47     /*
       
    48      * =============================================================
       
    49      * Set the various variables needed for the tests, then
       
    50      * specify what tests to run on each side.
       
    51      */
       
    52 
       
    53     /*
       
    54      * Should we run the client or server in a separate thread?
       
    55      * Both sides can throw exceptions, but do you have a preference
       
    56      * as to which side should be the main thread.
       
    57      */
       
    58     static boolean separateServerThread = false;
       
    59 
       
    60     /*
       
    61      * Where do we find the keystores?
       
    62      */
       
    63     static String pathToStores = "../etc";
       
    64     static String keyStoreFile = "keystore";
       
    65     static String trustStoreFile = "truststore";
       
    66     static String passwd = "passphrase";
       
    67 
       
    68     /*
       
    69      * Is the server ready to serve?
       
    70      */
       
    71     volatile static boolean serverReady = false;
       
    72 
       
    73     /*
       
    74      * Turn on SSL debugging?
       
    75      */
       
    76     static boolean debug = false;
       
    77 
       
    78     /*
       
    79      * If the client or server is doing some kind of object creation
       
    80      * that the other side depends on, and that thread prematurely
       
    81      * exits, you may experience a hang.  The test harness will
       
    82      * terminate all hung threads after its timeout has expired,
       
    83      * currently 3 minutes by default, but you might try to be
       
    84      * smart about it....
       
    85      */
       
    86 
       
    87     /*
       
    88      * Define the server side of the test.
       
    89      *
       
    90      * If the server prematurely exits, serverReady will be set to true
       
    91      * to avoid infinite hangs.
       
    92      */
       
    93     void doServerSide() throws Exception {
       
    94         SSLServerSocketFactory sslssf = getSSLServerSF();
       
    95         SSLServerSocket sslServerSocket =
       
    96             (SSLServerSocket) sslssf.createServerSocket(serverPort);
       
    97 
       
    98         // require client authentication.
       
    99         sslServerSocket.setNeedClientAuth(true);
       
   100 
       
   101         serverPort = sslServerSocket.getLocalPort();
       
   102 
       
   103         /*
       
   104          * Signal Client, we're ready for his connect.
       
   105          */
       
   106         serverReady = true;
       
   107 
       
   108         SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
       
   109         InputStream sslIS = sslSocket.getInputStream();
       
   110         OutputStream sslOS = sslSocket.getOutputStream();
       
   111 
       
   112         sslIS.read();
       
   113         sslOS.write('A');
       
   114         sslOS.flush();
       
   115 
       
   116         sslSocket.close();
       
   117     }
       
   118 
       
   119     /*
       
   120      * Define the client side of the test.
       
   121      *
       
   122      * If the server prematurely exits, serverReady will be set to true
       
   123      * to avoid infinite hangs.
       
   124      */
       
   125     void doClientSide() throws Exception {
       
   126 
       
   127         /*
       
   128          * Wait for server to get started.
       
   129          */
       
   130         while (!serverReady) {
       
   131             Thread.sleep(50);
       
   132         }
       
   133 
       
   134         SSLSocketFactory sslsf =
       
   135             (SSLSocketFactory) SSLSocketFactory.getDefault();
       
   136         SSLSocket sslSocket = (SSLSocket)
       
   137             sslsf.createSocket("localhost", serverPort);
       
   138 
       
   139         // enable TLSv1.1 only
       
   140         sslSocket.setEnabledProtocols(new String[] {"TLSv1.1"});
       
   141 
       
   142         InputStream sslIS = sslSocket.getInputStream();
       
   143         OutputStream sslOS = sslSocket.getOutputStream();
       
   144 
       
   145         sslOS.write('B');
       
   146         sslOS.flush();
       
   147         sslIS.read();
       
   148 
       
   149         sslSocket.close();
       
   150     }
       
   151 
       
   152     private SSLServerSocketFactory getSSLServerSF() throws Exception {
       
   153 
       
   154         char [] password =
       
   155             System.getProperty("javax.net.ssl.keyStorePassword").toCharArray();
       
   156         String keyFilename = System.getProperty("javax.net.ssl.keyStore");
       
   157 
       
   158         KeyStore ks = KeyStore.getInstance("JKS");
       
   159         ks.load(new FileInputStream(keyFilename), password);
       
   160 
       
   161         KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
       
   162         kmf.init(ks, password);
       
   163 
       
   164         KeyManager[] kms = kmf.getKeyManagers();
       
   165         TrustManager[] tms = new MyX509TM[] {new MyX509TM()};
       
   166 
       
   167         SSLContext ctx = SSLContext.getInstance("TLS");
       
   168         ctx.init(kms, tms, null);
       
   169 
       
   170         return ctx.getServerSocketFactory();
       
   171     }
       
   172 
       
   173 
       
   174     static class MyX509TM implements X509TrustManager {
       
   175         X509TrustManager tm;
       
   176 
       
   177         public void checkClientTrusted(X509Certificate[] chain,
       
   178             String authType) throws CertificateException {
       
   179             if (tm == null) {
       
   180                 initialize();
       
   181             }
       
   182             tm.checkClientTrusted(chain, authType);
       
   183         }
       
   184 
       
   185         public void checkServerTrusted(X509Certificate[] chain,
       
   186             String authType) throws CertificateException {
       
   187             if (tm == null) {
       
   188                 initialize();
       
   189             }
       
   190             tm.checkServerTrusted(chain, authType);
       
   191         }
       
   192 
       
   193         public X509Certificate[] getAcceptedIssuers() {
       
   194             // always return empty array
       
   195             return new X509Certificate[0];
       
   196         }
       
   197 
       
   198         private void initialize() throws CertificateException {
       
   199             String passwd =
       
   200                 System.getProperty("javax.net.ssl.trustStorePassword");
       
   201             char [] password = passwd.toCharArray();
       
   202             String trustFilename =
       
   203                 System.getProperty("javax.net.ssl.trustStore");
       
   204 
       
   205             try {
       
   206                 KeyStore ks = KeyStore.getInstance("JKS");
       
   207                 ks.load(new FileInputStream(trustFilename), password);
       
   208 
       
   209                 TrustManagerFactory tmf =
       
   210                         TrustManagerFactory.getInstance("PKIX");
       
   211                 tmf.init(ks);
       
   212                 tm = (X509TrustManager)tmf.getTrustManagers()[0];
       
   213             } catch (Exception e) {
       
   214                 throw new CertificateException("Unable to initialize TM");
       
   215             }
       
   216 
       
   217         }
       
   218     }
       
   219 
       
   220     /*
       
   221      * =============================================================
       
   222      * The remainder is just support stuff
       
   223      */
       
   224 
       
   225     // use any free port by default
       
   226     volatile int serverPort = 0;
       
   227 
       
   228     volatile Exception serverException = null;
       
   229     volatile Exception clientException = null;
       
   230 
       
   231     public static void main(String[] args) throws Exception {
       
   232         // MD5 is used in this test case, don't disable MD5 algorithm.
       
   233         Security.setProperty(
       
   234                 "jdk.certpath.disabledAlgorithms", "MD2, RSA keySize < 1024");
       
   235 
       
   236         String keyFilename =
       
   237             System.getProperty("test.src", ".") + "/" + pathToStores +
       
   238                 "/" + keyStoreFile;
       
   239         String trustFilename =
       
   240             System.getProperty("test.src", ".") + "/" + pathToStores +
       
   241                 "/" + trustStoreFile;
       
   242 
       
   243         System.setProperty("javax.net.ssl.keyStore", keyFilename);
       
   244         System.setProperty("javax.net.ssl.keyStorePassword", passwd);
       
   245         System.setProperty("javax.net.ssl.trustStore", trustFilename);
       
   246         System.setProperty("javax.net.ssl.trustStorePassword", passwd);
       
   247 
       
   248         if (debug)
       
   249             System.setProperty("javax.net.debug", "all");
       
   250 
       
   251         /*
       
   252          * Start the tests.
       
   253          */
       
   254         new EmptyCertificateAuthorities();
       
   255     }
       
   256 
       
   257     Thread clientThread = null;
       
   258     Thread serverThread = null;
       
   259 
       
   260     /*
       
   261      * Primary constructor, used to drive remainder of the test.
       
   262      *
       
   263      * Fork off the other side, then do your work.
       
   264      */
       
   265     EmptyCertificateAuthorities() throws Exception {
       
   266         try {
       
   267             if (separateServerThread) {
       
   268                 startServer(true);
       
   269                 startClient(false);
       
   270             } else {
       
   271                 startClient(true);
       
   272                 startServer(false);
       
   273             }
       
   274         } catch (Exception e) {
       
   275             // swallow for now.  Show later
       
   276         }
       
   277 
       
   278         /*
       
   279          * Wait for other side to close down.
       
   280          */
       
   281         if (separateServerThread) {
       
   282             serverThread.join();
       
   283         } else {
       
   284             clientThread.join();
       
   285         }
       
   286 
       
   287         /*
       
   288          * When we get here, the test is pretty much over.
       
   289          * Which side threw the error?
       
   290          */
       
   291         Exception local;
       
   292         Exception remote;
       
   293         String whichRemote;
       
   294 
       
   295         if (separateServerThread) {
       
   296             remote = serverException;
       
   297             local = clientException;
       
   298             whichRemote = "server";
       
   299         } else {
       
   300             remote = clientException;
       
   301             local = serverException;
       
   302             whichRemote = "client";
       
   303         }
       
   304 
       
   305         /*
       
   306          * If both failed, return the curthread's exception, but also
       
   307          * print the remote side Exception
       
   308          */
       
   309         if ((local != null) && (remote != null)) {
       
   310             System.out.println(whichRemote + " also threw:");
       
   311             remote.printStackTrace();
       
   312             System.out.println();
       
   313             throw local;
       
   314         }
       
   315 
       
   316         if (remote != null) {
       
   317             throw remote;
       
   318         }
       
   319 
       
   320         if (local != null) {
       
   321             throw local;
       
   322         }
       
   323     }
       
   324 
       
   325     void startServer(boolean newThread) throws Exception {
       
   326         if (newThread) {
       
   327             serverThread = new Thread() {
       
   328                 public void run() {
       
   329                     try {
       
   330                         doServerSide();
       
   331                     } catch (Exception e) {
       
   332                         /*
       
   333                          * Our server thread just died.
       
   334                          *
       
   335                          * Release the client, if not active already...
       
   336                          */
       
   337                         System.err.println("Server died...");
       
   338                         serverReady = true;
       
   339                         serverException = e;
       
   340                     }
       
   341                 }
       
   342             };
       
   343             serverThread.start();
       
   344         } else {
       
   345             try {
       
   346                 doServerSide();
       
   347             } catch (Exception e) {
       
   348                 serverException = e;
       
   349             } finally {
       
   350                 serverReady = true;
       
   351             }
       
   352         }
       
   353     }
       
   354 
       
   355     void startClient(boolean newThread) throws Exception {
       
   356         if (newThread) {
       
   357             clientThread = new Thread() {
       
   358                 public void run() {
       
   359                     try {
       
   360                         doClientSide();
       
   361                     } catch (Exception e) {
       
   362                         /*
       
   363                          * Our client thread just died.
       
   364                          */
       
   365                         System.err.println("Client died...");
       
   366                         clientException = e;
       
   367                     }
       
   368                 }
       
   369             };
       
   370             clientThread.start();
       
   371         } else {
       
   372             try {
       
   373                 doClientSide();
       
   374             } catch (Exception e) {
       
   375                 clientException = e;
       
   376             }
       
   377         }
       
   378     }
       
   379 }