jdk/test/javax/net/ssl/SSLEngine/TestAllSuites.java
changeset 23052 241885315119
parent 7043 5e2d1edeb2c7
equal deleted inserted replaced
23051:501d8479f798 23052:241885315119
       
     1 /*
       
     2  * Copyright (c) 2003, 2010, 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.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /*
       
    25  * @test
       
    26  * @bug 4495742
       
    27  * @ignore JSSE supported cipher suites are changed with CR 6916074,
       
    28  *     need to update this test case in JDK 7 soon
       
    29  * @run main/timeout=180 TestAllSuites
       
    30  * @summary Add non-blocking SSL/TLS functionality, usable with any
       
    31  *      I/O abstraction
       
    32  *
       
    33  * Iterate through all the suites using both TLS and SSLv3, and turn
       
    34  * SSLv2Hello off and on.  Exchange some bytes and shutdown.
       
    35  *
       
    36  * @author Brad Wetmore
       
    37  */
       
    38 
       
    39 import javax.net.ssl.*;
       
    40 import javax.net.ssl.SSLEngineResult.*;
       
    41 import java.io.*;
       
    42 import java.security.*;
       
    43 import java.nio.*;
       
    44 import java.util.*;
       
    45 
       
    46 public class TestAllSuites {
       
    47 
       
    48     private static boolean debug = false;
       
    49 
       
    50     private SSLContext sslc;
       
    51     private SSLEngine ssle1;    // client
       
    52     private SSLEngine ssle2;    // server
       
    53 
       
    54     private static String pathToStores = "../etc";
       
    55     private static String keyStoreFile = "keystore";
       
    56     private static String trustStoreFile = "truststore";
       
    57     private static String passwd = "passphrase";
       
    58 
       
    59     private static String keyFilename =
       
    60             System.getProperty("test.src", "./") + "/" + pathToStores +
       
    61                 "/" + keyStoreFile;
       
    62     private static String trustFilename =
       
    63             System.getProperty("test.src", "./") + "/" + pathToStores +
       
    64                 "/" + trustStoreFile;
       
    65 
       
    66     private ByteBuffer appOut1;         // write side of ssle1
       
    67     private ByteBuffer appIn1;          // read side of ssle1
       
    68     private ByteBuffer appOut2;         // write side of ssle2
       
    69     private ByteBuffer appIn2;          // read side of ssle2
       
    70 
       
    71     private ByteBuffer oneToTwo;        // "reliable" transport ssle1->ssle2
       
    72     private ByteBuffer twoToOne;        // "reliable" transport ssle2->ssle1
       
    73 
       
    74     String [][] protocols = new String [][] {
       
    75         { "SSLv3" },
       
    76         { "TLSv1" },
       
    77         { "SSLv3", "SSLv2Hello"},
       
    78         { "TLSv1", "SSLv2Hello"}
       
    79     };
       
    80 
       
    81     /*
       
    82      * Majority of the test case is here, setup is done below.
       
    83      */
       
    84 
       
    85     private void createSSLEngines() throws Exception {
       
    86         ssle1 = sslc.createSSLEngine("client", 1);
       
    87         ssle1.setUseClientMode(true);
       
    88 
       
    89         ssle2 = sslc.createSSLEngine("server", 2);
       
    90         ssle2.setUseClientMode(false);
       
    91     }
       
    92 
       
    93     private void test() throws Exception {
       
    94 
       
    95         createSSLEngines();
       
    96         String [] suites = ssle1.getSupportedCipherSuites();
       
    97 
       
    98         for (int i = 0; i < suites.length; i++) {
       
    99             for (int j = 0; j < protocols.length; j++) {
       
   100                 createSSLEngines();
       
   101                 runTest(suites[i], protocols[j]);
       
   102             }
       
   103         }
       
   104     }
       
   105 
       
   106     private void runTest(String suite, String [] protocols) throws Exception {
       
   107 
       
   108         boolean dataDone = false;
       
   109 
       
   110         System.out.println("======================================");
       
   111         System.out.println("Testing: " + suite);
       
   112         for (int i = 0; i < protocols.length; i++) {
       
   113             System.out.print(protocols[i] + " ");
       
   114         }
       
   115 
       
   116         /*
       
   117          * Don't run the Kerberized suites for now.
       
   118          */
       
   119         if (suite.startsWith("TLS_KRB5")) {
       
   120             System.out.println("Ignoring Kerberized suite");
       
   121             return;
       
   122         }
       
   123 
       
   124         /*
       
   125          * Don't run the SCSV suite
       
   126          */
       
   127         if (suite.equals("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) {
       
   128             System.out.println("Ignoring SCSV suite");
       
   129             return;
       
   130         }
       
   131 
       
   132 
       
   133         if (!suite.contains("DH_anon")) {
       
   134             ssle2.setNeedClientAuth(true);
       
   135         }
       
   136 
       
   137         String [] suites = new String [] { suite };
       
   138 
       
   139         ssle1.setEnabledCipherSuites(suites);
       
   140         ssle2.setEnabledCipherSuites(suites);
       
   141 
       
   142         ssle1.setEnabledProtocols(protocols);
       
   143         ssle2.setEnabledProtocols(protocols);
       
   144 
       
   145         createBuffers();
       
   146 
       
   147         SSLEngineResult result1;        // ssle1's results from last operation
       
   148         SSLEngineResult result2;        // ssle2's results from last operation
       
   149 
       
   150         Date start = new Date();
       
   151         while (!isEngineClosed(ssle1) || !isEngineClosed(ssle2)) {
       
   152 
       
   153             log("----------------");
       
   154 
       
   155             result1 = ssle1.wrap(appOut1, oneToTwo);
       
   156             result2 = ssle2.wrap(appOut2, twoToOne);
       
   157 
       
   158             log("wrap1:  " + result1);
       
   159             log("oneToTwo  = " + oneToTwo);
       
   160             log("");
       
   161 
       
   162             log("wrap2:  " + result2);
       
   163             log("twoToOne  = " + twoToOne);
       
   164 
       
   165             runDelegatedTasks(result1, ssle1);
       
   166             runDelegatedTasks(result2, ssle2);
       
   167 
       
   168             oneToTwo.flip();
       
   169             twoToOne.flip();
       
   170 
       
   171             log("----");
       
   172 
       
   173             result1 = ssle1.unwrap(twoToOne, appIn1);
       
   174             result2 = ssle2.unwrap(oneToTwo, appIn2);
       
   175 
       
   176             log("unwrap1: " + result1);
       
   177             log("twoToOne  = " + twoToOne);
       
   178             log("");
       
   179 
       
   180             log("unwrap2: " + result2);
       
   181             log("oneToTwo  = " + oneToTwo);
       
   182 
       
   183             runDelegatedTasks(result1, ssle1);
       
   184             runDelegatedTasks(result2, ssle2);
       
   185 
       
   186             oneToTwo.compact();
       
   187             twoToOne.compact();
       
   188 
       
   189             /*
       
   190              * If we've transfered all the data between app1 and app2,
       
   191              * we try to close and see what that gets us.
       
   192              */
       
   193             if (!dataDone && (appOut1.limit() == appIn2.position()) &&
       
   194                     (appOut2.limit() == appIn1.position())) {
       
   195 
       
   196                 checkTransfer(appOut1, appIn2);
       
   197                 checkTransfer(appOut2, appIn1);
       
   198 
       
   199                 log("Closing ssle1's *OUTBOUND*...");
       
   200                 ssle1.closeOutbound();
       
   201                 dataDone = true;
       
   202             }
       
   203         }
       
   204 
       
   205         /*
       
   206          * Just for grins, try closing again, make sure nothing
       
   207          * strange is happening after we're closed.
       
   208          */
       
   209         ssle1.closeInbound();
       
   210         ssle1.closeOutbound();
       
   211 
       
   212         ssle2.closeInbound();
       
   213         ssle2.closeOutbound();
       
   214 
       
   215         appOut1.rewind();
       
   216         appIn1.clear();
       
   217         oneToTwo.clear();
       
   218 
       
   219         result1 = ssle1.wrap(appOut1, oneToTwo);
       
   220         checkResult(result1);
       
   221 
       
   222         result1 = ssle1.unwrap(oneToTwo, appIn1);
       
   223         checkResult(result1);
       
   224 
       
   225         System.out.println("Test Passed.");
       
   226         System.out.println("\n======================================");
       
   227 
       
   228         Date end = new Date();
       
   229         elapsed += end.getTime() - start.getTime();
       
   230 
       
   231     }
       
   232 
       
   233     static long elapsed = 0;
       
   234 
       
   235     private static void checkResult(SSLEngineResult result) throws Exception {
       
   236         if ((result.getStatus() != Status.CLOSED) ||
       
   237                 (result.getHandshakeStatus() !=
       
   238                     HandshakeStatus.NOT_HANDSHAKING) ||
       
   239                 (result.bytesConsumed() != 0) ||
       
   240                 (result.bytesProduced() != 0)) {
       
   241             throw new Exception("Unexpected close status");
       
   242         }
       
   243     }
       
   244 
       
   245     public static void main(String args[]) throws Exception {
       
   246 
       
   247         TestAllSuites tas;
       
   248 
       
   249         tas = new TestAllSuites();
       
   250 
       
   251         tas.createSSLEngines();
       
   252 
       
   253         tas.test();
       
   254 
       
   255         System.out.println("All Tests Passed.");
       
   256         System.out.println("Elapsed time: " + elapsed / 1000.0);
       
   257     }
       
   258 
       
   259     /*
       
   260      * **********************************************************
       
   261      * Majority of the test case is above, below is just setup stuff
       
   262      * **********************************************************
       
   263      */
       
   264 
       
   265     public TestAllSuites() throws Exception {
       
   266         sslc = getSSLContext(keyFilename, trustFilename);
       
   267     }
       
   268 
       
   269     /*
       
   270      * Create an initialized SSLContext to use for this test.
       
   271      */
       
   272     private SSLContext getSSLContext(String keyFile, String trustFile)
       
   273             throws Exception {
       
   274 
       
   275         KeyStore ks = KeyStore.getInstance("JKS");
       
   276         KeyStore ts = KeyStore.getInstance("JKS");
       
   277 
       
   278         char[] passphrase = "passphrase".toCharArray();
       
   279 
       
   280         ks.load(new FileInputStream(keyFile), passphrase);
       
   281         ts.load(new FileInputStream(trustFile), passphrase);
       
   282 
       
   283         KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
       
   284         kmf.init(ks, passphrase);
       
   285 
       
   286         TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
       
   287         tmf.init(ts);
       
   288 
       
   289         SSLContext sslCtx = SSLContext.getInstance("TLS");
       
   290 
       
   291         sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
       
   292 
       
   293         return sslCtx;
       
   294     }
       
   295 
       
   296     private void createBuffers() {
       
   297         // Size the buffers as appropriate.
       
   298 
       
   299         SSLSession session = ssle1.getSession();
       
   300         int appBufferMax = session.getApplicationBufferSize();
       
   301         int netBufferMax = session.getPacketBufferSize();
       
   302 
       
   303         appIn1 = ByteBuffer.allocateDirect(appBufferMax + 50);
       
   304         appIn2 = ByteBuffer.allocateDirect(appBufferMax + 50);
       
   305 
       
   306         oneToTwo = ByteBuffer.allocateDirect(netBufferMax);
       
   307         twoToOne = ByteBuffer.allocateDirect(netBufferMax);
       
   308 
       
   309         appOut1 = ByteBuffer.wrap("Hi Engine2, I'm SSLEngine1".getBytes());
       
   310         appOut2 = ByteBuffer.wrap("Hello Engine1, I'm SSLEngine2".getBytes());
       
   311 
       
   312         log("AppOut1 = " + appOut1);
       
   313         log("AppOut2 = " + appOut2);
       
   314         log("");
       
   315     }
       
   316 
       
   317     private static void runDelegatedTasks(SSLEngineResult result,
       
   318             SSLEngine engine) throws Exception {
       
   319 
       
   320         if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
       
   321             Runnable runnable;
       
   322             while ((runnable = engine.getDelegatedTask()) != null) {
       
   323                 log("running delegated task...");
       
   324                 runnable.run();
       
   325             }
       
   326         }
       
   327     }
       
   328 
       
   329     private static boolean isEngineClosed(SSLEngine engine) {
       
   330         return (engine.isOutboundDone() && engine.isInboundDone());
       
   331     }
       
   332 
       
   333     private static void checkTransfer(ByteBuffer a, ByteBuffer b)
       
   334             throws Exception {
       
   335         a.flip();
       
   336         b.flip();
       
   337 
       
   338         if (!a.equals(b)) {
       
   339             throw new Exception("Data didn't transfer cleanly");
       
   340         } else {
       
   341             log("Data transferred cleanly");
       
   342         }
       
   343 
       
   344         a.position(a.limit());
       
   345         b.position(b.limit());
       
   346         a.limit(a.capacity());
       
   347         b.limit(b.capacity());
       
   348     }
       
   349 
       
   350     private static void log(String str) {
       
   351         if (debug) {
       
   352             System.out.println(str);
       
   353         }
       
   354     }
       
   355 }