Path: blob/master/test/jdk/javax/net/ssl/ciphersuites/DisabledAlgorithms.java
41152 views
/*1* Copyright (c) 2015, 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* @test25* @bug 8076221 821188326* @summary Check if weak cipher suites are disabled27* @modules jdk.crypto.ec28* @run main/othervm DisabledAlgorithms default29* @run main/othervm DisabledAlgorithms empty30*/3132import java.io.BufferedInputStream;33import java.io.BufferedOutputStream;34import java.io.IOException;35import java.io.InputStream;36import java.io.OutputStream;37import java.security.NoSuchAlgorithmException;38import java.security.Security;39import java.util.concurrent.TimeUnit;40import javax.net.ssl.SSLContext;41import javax.net.ssl.SSLHandshakeException;42import javax.net.ssl.SSLServerSocket;43import javax.net.ssl.SSLServerSocketFactory;44import javax.net.ssl.SSLSocket;45import javax.net.ssl.SSLSocketFactory;4647public class DisabledAlgorithms {4849private static final String pathToStores = "../etc";50private static final String keyStoreFile = "keystore";51private static final String trustStoreFile = "truststore";52private static final String passwd = "passphrase";5354private static final String keyFilename =55System.getProperty("test.src", "./") + "/" + pathToStores +56"/" + keyStoreFile;5758private static final String trustFilename =59System.getProperty("test.src", "./") + "/" + pathToStores +60"/" + trustStoreFile;6162// supported RC4, NULL, and anon cipher suites63// it does not contain KRB5 cipher suites because they need a KDC64private static final String[] rc4_null_anon_ciphersuites = new String[] {65"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",66"TLS_ECDHE_RSA_WITH_RC4_128_SHA",67"SSL_RSA_WITH_RC4_128_SHA",68"TLS_ECDH_ECDSA_WITH_RC4_128_SHA",69"TLS_ECDH_RSA_WITH_RC4_128_SHA",70"SSL_RSA_WITH_RC4_128_MD5",71"TLS_ECDH_anon_WITH_RC4_128_SHA",72"SSL_DH_anon_WITH_RC4_128_MD5",73"SSL_RSA_WITH_NULL_MD5",74"SSL_RSA_WITH_NULL_SHA",75"TLS_RSA_WITH_NULL_SHA256",76"TLS_ECDH_ECDSA_WITH_NULL_SHA",77"TLS_ECDHE_ECDSA_WITH_NULL_SHA",78"TLS_ECDH_RSA_WITH_NULL_SHA",79"TLS_ECDHE_RSA_WITH_NULL_SHA",80"TLS_ECDH_anon_WITH_NULL_SHA",81"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",82"SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",83"SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",84"SSL_DH_anon_WITH_DES_CBC_SHA",85"SSL_DH_anon_WITH_RC4_128_MD5",86"TLS_DH_anon_WITH_AES_128_CBC_SHA",87"TLS_DH_anon_WITH_AES_128_CBC_SHA256",88"TLS_DH_anon_WITH_AES_128_GCM_SHA256",89"TLS_DH_anon_WITH_AES_256_CBC_SHA",90"TLS_DH_anon_WITH_AES_256_CBC_SHA256",91"TLS_DH_anon_WITH_AES_256_GCM_SHA384",92"TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",93"TLS_ECDH_anon_WITH_AES_128_CBC_SHA",94"TLS_ECDH_anon_WITH_AES_256_CBC_SHA",95"TLS_ECDH_anon_WITH_NULL_SHA",96"TLS_ECDH_anon_WITH_RC4_128_SHA"97};9899public static void main(String[] args) throws Exception {100if (args.length < 1) {101throw new RuntimeException("No parameters specified");102}103104System.setProperty("javax.net.ssl.keyStore", keyFilename);105System.setProperty("javax.net.ssl.keyStorePassword", passwd);106System.setProperty("javax.net.ssl.trustStore", trustFilename);107System.setProperty("javax.net.ssl.trustStorePassword", passwd);108109switch (args[0]) {110case "default":111// use default jdk.tls.disabledAlgorithms112System.out.println("jdk.tls.disabledAlgorithms = "113+ Security.getProperty("jdk.tls.disabledAlgorithms"));114115// check if RC4, NULL, and anon cipher suites116// can't be used by default117checkFailure(rc4_null_anon_ciphersuites);118break;119case "empty":120// reset jdk.tls.disabledAlgorithms121Security.setProperty("jdk.tls.disabledAlgorithms", "");122System.out.println("jdk.tls.disabledAlgorithms = "123+ Security.getProperty("jdk.tls.disabledAlgorithms"));124125// check if RC4, NULL, and anon cipher suites can be used126// if jdk.tls.disabledAlgorithms is empty127checkSuccess(rc4_null_anon_ciphersuites);128break;129default:130throw new RuntimeException("Wrong parameter: " + args[0]);131}132133System.out.println("Test passed");134}135136/*137* Checks if that specified cipher suites cannot be used.138*/139private static void checkFailure(String[] ciphersuites) throws Exception {140try (SSLServer server = SSLServer.init(ciphersuites)) {141startNewThread(server);142while (!server.isRunning()) {143sleep();144}145146int port = server.getPort();147for (String ciphersuite : ciphersuites) {148try (SSLClient client = SSLClient.init(port, ciphersuite)) {149client.connect();150throw new RuntimeException("Expected SSLHandshakeException "151+ "not thrown");152} catch (SSLHandshakeException e) {153System.out.println("Expected exception on client side: "154+ e);155}156}157158while (server.isRunning()) {159sleep();160}161162if (!server.sslError()) {163throw new RuntimeException("Expected SSL exception "164+ "not thrown on server side");165}166}167168}169170/*171* Checks if specified cipher suites can be used.172*/173private static void checkSuccess(String[] ciphersuites) throws Exception {174try (SSLServer server = SSLServer.init(ciphersuites)) {175startNewThread(server);176while (!server.isRunning()) {177sleep();178}179180int port = server.getPort();181for (String ciphersuite : ciphersuites) {182try (SSLClient client = SSLClient.init(port, ciphersuite)) {183client.connect();184String negotiated = client.getNegotiatedCipherSuite();185System.out.println("Negotiated cipher suite: "186+ negotiated);187if (!negotiated.equals(ciphersuite)) {188throw new RuntimeException("Unexpected cipher suite: "189+ negotiated);190}191}192}193194server.stop();195while (server.isRunning()) {196sleep();197}198199if (server.error()) {200throw new RuntimeException("Unexpected error on server side");201}202}203204}205206private static Thread startNewThread(SSLServer server) {207Thread serverThread = new Thread(server, "SSL server thread");208serverThread.setDaemon(true);209serverThread.start();210return serverThread;211}212213private static void sleep() {214try {215TimeUnit.MILLISECONDS.sleep(50);216} catch (InterruptedException e) {217// do nothing218}219}220221static class SSLServer implements Runnable, AutoCloseable {222223private final SSLServerSocket ssocket;224private volatile boolean stopped = false;225private volatile boolean running = false;226private volatile boolean sslError = false;227private volatile boolean otherError = false;228229private SSLServer(SSLServerSocket ssocket) {230this.ssocket = ssocket;231}232233@Override234public void run() {235System.out.println("Server: started");236running = true;237while (!stopped) {238try (SSLSocket socket = (SSLSocket) ssocket.accept()) {239System.out.println("Server: accepted client connection");240InputStream in = socket.getInputStream();241OutputStream out = socket.getOutputStream();242int b = in.read();243if (b < 0) {244throw new IOException("Unexpected EOF");245}246System.out.println("Server: send data: " + b);247out.write(b);248out.flush();249socket.getSession().invalidate();250} catch (SSLHandshakeException e) {251System.out.println("Server: run: " + e);252sslError = true;253stopped = true;254} catch (IOException e) {255if (!stopped) {256System.out.println("Server: run: unexpected exception: "257+ e);258e.printStackTrace();259otherError = true;260stopped = true;261} else {262System.out.println("Server: run: " + e);263System.out.println("The exception above occurred "264+ "because socket was closed, "265+ "please ignore it");266}267}268}269270System.out.println("Server: finished");271running = false;272}273274int getPort() {275return ssocket.getLocalPort();276}277278String[] getEnabledCiperSuites() {279return ssocket.getEnabledCipherSuites();280}281282boolean isRunning() {283return running;284}285286boolean sslError() {287return sslError;288}289290boolean error() {291return sslError || otherError;292}293294void stop() {295stopped = true;296if (!ssocket.isClosed()) {297try {298System.out.println("Server: close socket");299ssocket.close();300} catch (IOException e) {301System.out.println("Server: close: " + e);302}303}304}305306@Override307public void close() {308stop();309}310311static SSLServer init(String[] ciphersuites)312throws IOException {313SSLServerSocketFactory ssf = (SSLServerSocketFactory)314SSLServerSocketFactory.getDefault();315SSLServerSocket ssocket = (SSLServerSocket)316ssf.createServerSocket(0);317318if (ciphersuites != null) {319System.out.println("Server: enable cipher suites: "320+ java.util.Arrays.toString(ciphersuites));321ssocket.setEnabledCipherSuites(ciphersuites);322}323324return new SSLServer(ssocket);325}326}327328static class SSLClient implements AutoCloseable {329330private final SSLSocket socket;331332private SSLClient(SSLSocket socket) {333this.socket = socket;334}335336void connect() throws IOException {337System.out.println("Client: connect to server");338try (339BufferedInputStream bis = new BufferedInputStream(340socket.getInputStream());341BufferedOutputStream bos = new BufferedOutputStream(342socket.getOutputStream())) {343bos.write('x');344bos.flush();345346int read = bis.read();347if (read < 0) {348throw new IOException("Client: couldn't read a response");349}350socket.getSession().invalidate();351}352}353354String[] getEnabledCiperSuites() {355return socket.getEnabledCipherSuites();356}357358String getNegotiatedCipherSuite() {359return socket.getSession().getCipherSuite();360}361362@Override363public void close() throws Exception {364if (!socket.isClosed()) {365try {366socket.close();367} catch (IOException e) {368System.out.println("Client: close: " + e);369}370}371}372373static SSLClient init(int port)374throws NoSuchAlgorithmException, IOException {375return init(port, null);376}377378static SSLClient init(int port, String ciphersuite)379throws NoSuchAlgorithmException, IOException {380SSLContext context = SSLContext.getDefault();381SSLSocketFactory ssf = (SSLSocketFactory)382context.getSocketFactory();383SSLSocket socket = (SSLSocket) ssf.createSocket("localhost", port);384385if (ciphersuite != null) {386System.out.println("Client: enable cipher suite: "387+ ciphersuite);388socket.setEnabledCipherSuites(new String[] { ciphersuite });389}390391return new SSLClient(socket);392}393394}395396397}398399400