1 /*
  2  * Copyright (c) 2023, 2024, 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 import jdk.test.lib.process.ProcessTools;
 25 
 26 import javax.net.ssl.*;
 27 import java.io.IOException;
 28 import java.net.Socket;
 29 import java.nio.charset.StandardCharsets;
 30 import java.security.Security;
 31 import java.util.List;
 32 
 33 /*
 34  * @test id=Server
 35  * @bug 8301379
 36  * @library /test/lib
 37  * @summary Verify that Java will not negotiate disabled cipher suites when the
 38  * other side of the connection requests them.
 39  *
 40  * @library /javax/net/ssl/templates
 41  * @run main/othervm TLSWontNegotiateDisabledCipherAlgos server true
 42  */
 43 
 44 /*
 45  * @test id=Client
 46  * @bug 8301379
 47  * @library /test/lib
 48  * @summary Verify that Java will not negotiate disabled cipher suites when the
 49  * other side of the connection requests them.
 50  *
 51  * @library /javax/net/ssl/templates
 52  * @run main/othervm TLSWontNegotiateDisabledCipherAlgos server false
 53  */
 54 
 55 
 56 public class TLSWontNegotiateDisabledCipherAlgos {
 57 
 58     public static void main(String [] args) throws Exception {
 59         boolean useDisabledAlgo = Boolean.parseBoolean(args[1]);
 60         if (useDisabledAlgo) {
 61             Security.setProperty("jdk.tls.disabledAlgorithms", "");
 62         }
 63 
 64         if (args[0].equals("server")) {
 65             try (TLSServer server = new TLSServer(useDisabledAlgo)) {
 66                 List<String> command = List.of(
 67                         "TLSWontNegotiateDisabledCipherAlgos",
 68                         "client",
 69                         Boolean.toString(!useDisabledAlgo),
 70                         Integer.toString(server.getListeningPort())
 71                 );
 72                 ProcessBuilder builder = ProcessTools.createTestJavaProcessBuilder(command);
 73                 Process p = builder.inheritIO().start();
 74                 server.run();
 75                 p.destroy();
 76             }
 77         } else if (args[0].equals("client")) {
 78             try (TLSClient client = new TLSClient(Integer.parseInt(args[2]), useDisabledAlgo)) {
 79                 client.run();
 80             }
 81         }
 82     }
 83 
 84     private static class TLSClient extends SSLContextTemplate implements AutoCloseable {
 85         private final SSLSocket socket;
 86 
 87         public TLSClient(int portNumber, boolean useDisableAlgo) throws Exception {
 88             SSLContext context = createClientSSLContext();
 89             socket = (SSLSocket)context.getSocketFactory().createSocket("localhost", portNumber);
 90             if (useDisableAlgo) {
 91                 socket.setEnabledCipherSuites(DisabledAlgorithms.DISABLED_CIPHERSUITES);
 92             }
 93         }
 94 
 95         public void run() throws IOException {
 96             try {
 97                 socket.getOutputStream().write("SECRET MESSAGE".getBytes(StandardCharsets.UTF_8));
 98                 throw new RuntimeException("SSL handshake completed successfully.");
 99             } catch (SSLHandshakeException exc) {
100                 if (!exc.getMessage().equals("Received fatal alert: handshake_failure")) {
101                     throw new RuntimeException("Expected handshake_failure message. Got: "
102                             + "\"" + exc.getMessage() + "\" message.", exc);
103                 }
104             }
105         }
106 
107         @Override
108         public void close() throws Exception {
109             socket.close();
110         }
111     }
112 
113     private static class TLSServer extends SSLContextTemplate implements AutoCloseable {
114         private SSLServerSocket serverSocket;
115 
116         public TLSServer(boolean useDisableAlgo) throws Exception {
117             SSLContext ctx = createServerSSLContext();
118             serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(0);
119             if (useDisableAlgo) {
120                 serverSocket.setEnabledCipherSuites(DisabledAlgorithms.DISABLED_CIPHERSUITES);
121             }
122         }
123 
124         @Override
125         public void close() throws Exception {
126             serverSocket.close();
127         }
128 
129         public int getListeningPort() {
130             return serverSocket.getLocalPort();
131         }
132 
133         public void run() throws IOException {
134             try (Socket clientSocket = serverSocket.accept()) {
135                 try {
136                     byte[] bytes = clientSocket.getInputStream().readAllBytes();
137                     throw new RuntimeException("The expected SSLHandshakeException was not thrown.");
138                 } catch (SSLHandshakeException exc) {
139                     if (!exc.getMessage().contains("no cipher suites in common")) {
140                         throw exc;
141                     } else {
142                         System.out.println("Success: The connection could not be negotiated (as expected.)");
143                     }
144                 }
145             }
146         }
147     }
148 }