/* * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ // SunJSSE does not support dynamic system properties, no way to re-use // system properties in samevm/agentvm mode. /* * @test * @bug 8162362 * @summary Cannot enable previously default enabled cipher suites * @run main/othervm * CustomizedCipherSuites Default true * TLS_RSA_WITH_AES_128_CBC_SHA * SSL_RSA_WITH_DES_CBC_SHA * @run main/othervm * -Djdk.tls.client.cipherSuites="unknown" * CustomizedCipherSuites Default true * TLS_RSA_WITH_AES_128_CBC_SHA * SSL_RSA_WITH_DES_CBC_SHA * @run main/othervm * -Djdk.tls.client.cipherSuites="" * CustomizedCipherSuites Default true * TLS_RSA_WITH_AES_128_CBC_SHA * SSL_RSA_WITH_DES_CBC_SHA * @run main/othervm * -Djdk.tls.client.cipherSuites="SSL_RSA_WITH_DES_CBC_SHA" * CustomizedCipherSuites Default true * SSL_RSA_WITH_DES_CBC_SHA * TLS_RSA_WITH_AES_128_CBC_SHA * @run main/othervm * -Djdk.tls.server.cipherSuites="SSL_RSA_WITH_DES_CBC_SHA" * CustomizedCipherSuites Default false * SSL_RSA_WITH_DES_CBC_SHA * TLS_RSA_WITH_AES_128_CBC_SHA * @run main/othervm * -Djdk.tls.client.cipherSuites="TLS_RSA_WITH_AES_128_CBC_SHA,unknown,SSL_RSA_WITH_DES_CBC_SHA" * CustomizedCipherSuites Default true * SSL_RSA_WITH_DES_CBC_SHA * "" * @run main/othervm * -Djdk.tls.server.cipherSuites="TLS_RSA_WITH_AES_128_CBC_SHA,unknown,SSL_RSA_WITH_DES_CBC_SHA" * CustomizedCipherSuites Default false * TLS_RSA_WITH_AES_128_CBC_SHA * "" * @run main/othervm * -Djdk.tls.server.cipherSuites="SSL_RSA_WITH_DES_CBC_SHA" * CustomizedCipherSuites Default true * TLS_RSA_WITH_AES_128_CBC_SHA * SSL_RSA_WITH_DES_CBC_SHA * @run main/othervm * -Djdk.tls.client.cipherSuites="SSL_RSA_WITH_DES_CBC_SHA" * CustomizedCipherSuites Default false * TLS_RSA_WITH_AES_128_CBC_SHA * SSL_RSA_WITH_DES_CBC_SHA */ import javax.net.ssl.*; /** * Test the customized default cipher suites. * * This test is based on the behavior that SSL_RSA_WITH_DES_CBC_SHA is * disabled by default, and TLS_RSA_WITH_AES_128_CBC_SHA is enabled by * default in JDK. If the behavior is changed in the future, please * update the test cases above accordingly. */ public class CustomizedCipherSuites { private static String contextProtocol; private static boolean isClientMode; private static String enabledCipherSuite; private static String disabledCipherSuite; public static void main(String[] args) throws Exception { contextProtocol = trimQuotes(args[0]); isClientMode = Boolean.parseBoolean(args[1]); enabledCipherSuite = trimQuotes(args[2]); disabledCipherSuite = trimQuotes(args[3]); // // Create instance of SSLContext with the specified protocol. // SSLContext context = SSLContext.getInstance(contextProtocol); // Default SSLContext is initialized automatically. if (!contextProtocol.equals("Default")) { // Use default TK, KM and random. context.init((KeyManager[])null, (TrustManager[])null, null); } // SSLContext default parameters is client mode in JDK. if (isClientMode) { // // Check default parameters of the specified SSLContext protocol // SSLParameters parameters = context.getDefaultSSLParameters(); System.out.println("Checking SSLContext default parameters ..."); checkEnabledCiphers(parameters.getCipherSuites()); } // // Check supported parameters of the specified SSLContext protocol // SSLParameters parameters = context.getSupportedSSLParameters(); System.out.println("Checking SSLContext suppport parameters ..."); checkSupportedCiphers(parameters.getCipherSuites()); // // Check the default cipher suites of SSLEngine. // SSLEngine engine = context.createSSLEngine(); engine.setUseClientMode(isClientMode); System.out.println("Checking SSLEngine default cipher suites ..."); checkEnabledCiphers(engine.getEnabledCipherSuites()); // // Check the supported cipher suites of SSLEngine. // System.out.println("Checking SSLEngine supported cipher suites ..."); checkSupportedCiphers(engine.getSupportedCipherSuites()); if (isClientMode) { SSLSocketFactory factory = context.getSocketFactory(); // Use an unconnected socket. try (SSLSocket socket = (SSLSocket)factory.createSocket()) { // // Check the default cipher suites of SSLSocket. // System.out.println( "Checking SSLSocket default cipher suites ..."); checkEnabledCiphers(socket.getEnabledCipherSuites()); // // Check the supported cipher suites of SSLSocket. // System.out.println( "Checking SSLSocket supported cipher suites ..."); checkSupportedCiphers(socket.getSupportedCipherSuites()); } } else { SSLServerSocketFactory factory = context.getServerSocketFactory(); // Use an unbound server socket. try (SSLServerSocket socket = (SSLServerSocket)factory.createServerSocket()) { // // Check the default cipher suites of SSLServerSocket. // System.out.println( "Checking SSLServerSocket default cipher suites ..."); checkEnabledCiphers(socket.getEnabledCipherSuites()); // // Check the supported cipher suites of SSLServerSocket. // System.out.println( "Checking SSLServerSocket supported cipher suites ..."); checkSupportedCiphers(socket.getSupportedCipherSuites()); } } System.out.println("\t... Success"); } private static void checkEnabledCiphers( String[] ciphers) throws Exception { if (ciphers.length == 0) { throw new Exception("No default cipher suites"); } boolean isMatch = false; if (enabledCipherSuite.isEmpty()) { // Don't check if not specify the expected cipher suite. isMatch = true; } boolean isBroken = false; for (String cipher : ciphers) { System.out.println("\tdefault cipher suite " + cipher); if (!enabledCipherSuite.isEmpty() && cipher.equals(enabledCipherSuite)) { isMatch = true; } if (!disabledCipherSuite.isEmpty() && cipher.equals(disabledCipherSuite)) { isBroken = true; } } if (!isMatch) { throw new Exception( "Cipher suite " + enabledCipherSuite + " should be enabled"); } if (isBroken) { throw new Exception( "Cipher suite " + disabledCipherSuite + " should be disabled"); } } private static void checkSupportedCiphers( String[] ciphers) throws Exception { if (ciphers.length == 0) { throw new Exception("No supported cipher suites"); } boolean hasEnabledCipherSuite = enabledCipherSuite.isEmpty(); boolean hasDisabledCipherSuite = disabledCipherSuite.isEmpty(); for (String cipher : ciphers) { System.out.println("\tsupported cipher suite " + cipher); if (!enabledCipherSuite.isEmpty() && cipher.equals(enabledCipherSuite)) { hasEnabledCipherSuite = true; } if (!disabledCipherSuite.isEmpty() && cipher.equals(disabledCipherSuite)) { hasDisabledCipherSuite = true; } } if (!hasEnabledCipherSuite) { throw new Exception( "Cipher suite " + enabledCipherSuite + " should be supported"); } if (!hasDisabledCipherSuite) { throw new Exception( "Cipher suite " + disabledCipherSuite + " should be supported"); } } private static String trimQuotes(String candidate) { if (candidate != null && candidate.length() != 0) { // Remove double quote marks from beginning/end of the string. if (candidate.length() > 1 && candidate.charAt(0) == '"' && candidate.charAt(candidate.length() - 1) == '"') { return candidate.substring(1, candidate.length() - 1); } } return candidate; } }