1 /* 2 * Copyright (c) 2001, 2018, 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 // SunJSSE does not support dynamic system properties, no way to re-use 25 // system properties in samevm/agentvm mode. 26 27 /* 28 * @test 29 * @bug 4416068 4478803 4479736 30 * @summary 4273544 JSSE request for function forceV3ClientHello() 31 * 4479736 setEnabledProtocols API does not work correctly 32 * 4478803 Need APIs to determine the protocol versions used in an SSL 33 * session 34 * 4701722 protocol mismatch exceptions should be consistent between 35 * SSLv3 and TLSv1 36 * @library /javax/net/ssl/templates 37 * @run main/othervm TestEnabledProtocols 38 * @author Ram Marti 39 */ 40 41 import java.io.InputStream; 42 import java.io.InterruptedIOException; 43 import java.io.OutputStream; 44 import java.security.Security; 45 import java.util.Arrays; 46 47 import javax.net.ssl.SSLException; 48 import javax.net.ssl.SSLHandshakeException; 49 import javax.net.ssl.SSLServerSocket; 50 import javax.net.ssl.SSLSocket; 51 52 public class TestEnabledProtocols extends SSLSocketTemplate { 53 54 private final String[] serverProtocols; 55 private final String[] clientProtocols; 56 private final boolean exceptionExpected; 57 private final String selectedProtocol; 58 TestEnabledProtocols(String[] serverProtocols, String[] clientProtocols, boolean exceptionExpected, String selectedProtocol)59 public TestEnabledProtocols(String[] serverProtocols, 60 String[] clientProtocols, boolean exceptionExpected, 61 String selectedProtocol) { 62 this.serverProtocols = serverProtocols; 63 this.clientProtocols = clientProtocols; 64 this.exceptionExpected = exceptionExpected; 65 this.selectedProtocol = selectedProtocol; 66 } 67 68 @Override configureServerSocket(SSLServerSocket sslServerSocket)69 protected void configureServerSocket(SSLServerSocket sslServerSocket) { 70 sslServerSocket.setEnabledProtocols(serverProtocols); 71 } 72 73 @Override runServerApplication(SSLSocket socket)74 protected void runServerApplication(SSLSocket socket) throws Exception { 75 try { 76 socket.startHandshake(); 77 78 InputStream in = socket.getInputStream(); 79 OutputStream out = socket.getOutputStream(); 80 out.write(280); 81 in.read(); 82 } catch (SSLHandshakeException se) { 83 // ignore it; this is part of the testing 84 // log it for debugging 85 System.out.println("Server SSLHandshakeException:"); 86 se.printStackTrace(System.out); 87 } catch (InterruptedIOException ioe) { 88 // must have been interrupted, no harm 89 } catch (SSLException ssle) { 90 // The client side may have closed the socket. 91 System.out.println("Server SSLException:"); 92 ssle.printStackTrace(System.out); 93 } catch (Exception e) { 94 System.out.println("Server exception:"); 95 e.printStackTrace(System.out); 96 throw new RuntimeException(e); 97 } 98 } 99 100 @Override runClientApplication(SSLSocket sslSocket)101 protected void runClientApplication(SSLSocket sslSocket) throws Exception { 102 try { 103 System.out.println("=== Starting new test run ==="); 104 showProtocols("server", serverProtocols); 105 showProtocols("client", clientProtocols); 106 107 sslSocket.setEnabledProtocols(clientProtocols); 108 sslSocket.startHandshake(); 109 110 String protocolName = sslSocket.getSession().getProtocol(); 111 System.out.println("Protocol name after getSession is " + 112 protocolName); 113 114 if (protocolName.equals(selectedProtocol)) { 115 System.out.println("** Success **"); 116 } else { 117 System.out.println("** FAILURE ** "); 118 throw new RuntimeException 119 ("expected protocol " + selectedProtocol + 120 " but using " + protocolName); 121 } 122 123 InputStream in = sslSocket.getInputStream(); 124 OutputStream out = sslSocket.getOutputStream(); 125 in.read(); 126 out.write(280); 127 } catch (SSLHandshakeException e) { 128 if (!exceptionExpected) { 129 System.out.println( 130 "Client got UNEXPECTED SSLHandshakeException:"); 131 e.printStackTrace(System.out); 132 System.out.println("** FAILURE **"); 133 throw new RuntimeException(e); 134 } else { 135 System.out.println( 136 "Client got expected SSLHandshakeException:"); 137 e.printStackTrace(System.out); 138 System.out.println("** Success **"); 139 } 140 } catch (Exception e) { 141 System.out.println("Client got UNEXPECTED Exception:"); 142 e.printStackTrace(System.out); 143 System.out.println("** FAILURE **"); 144 throw new RuntimeException(e); 145 } 146 } 147 main(String[] args)148 public static void main(String[] args) throws Exception { 149 Security.setProperty("jdk.tls.disabledAlgorithms", ""); 150 151 runCase(new String[] { "TLSv1" }, 152 new String[] { "TLSv1" }, 153 false, "TLSv1"); 154 runCase(new String[] { "TLSv1" }, 155 new String[] { "TLSv1", "SSLv2Hello" }, 156 true, null); 157 runCase(new String[] { "TLSv1" }, 158 new String[] { "TLSv1", "SSLv3" }, 159 false, "TLSv1"); 160 runCase(new String[] { "TLSv1" }, 161 new String[] { "SSLv3", "SSLv2Hello" }, 162 true, null); 163 runCase(new String[] { "TLSv1" }, 164 new String[] { "SSLv3" }, 165 true, null); 166 runCase(new String[] { "TLSv1" }, 167 new String[] { "TLSv1", "SSLv3", "SSLv2Hello" }, 168 true, null); 169 170 runCase(new String[] { "TLSv1", "SSLv2Hello" }, 171 new String[] { "TLSv1" }, 172 false, "TLSv1"); 173 runCase(new String[] { "TLSv1", "SSLv2Hello" }, 174 new String[] { "TLSv1", "SSLv2Hello" }, 175 false, "TLSv1"); 176 runCase(new String[] { "TLSv1", "SSLv2Hello" }, 177 new String[] { "TLSv1", "SSLv3" }, 178 false, "TLSv1"); 179 runCase(new String[] { "TLSv1", "SSLv2Hello" }, 180 new String[] { "SSLv3", "SSLv2Hello" }, 181 true, null); 182 runCase(new String[] { "TLSv1", "SSLv2Hello" }, 183 new String[] { "SSLv3" }, 184 true, null); 185 runCase(new String[] { "TLSv1", "SSLv2Hello" }, 186 new String[] { "TLSv1", "SSLv3", "SSLv2Hello" }, 187 false, "TLSv1"); 188 189 runCase(new String[] { "TLSv1", "SSLv3" }, 190 new String[] { "TLSv1" }, 191 false, "TLSv1"); 192 runCase(new String[] { "TLSv1", "SSLv3" }, 193 new String[] { "TLSv1", "SSLv2Hello" }, 194 true, null); 195 runCase(new String[] { "TLSv1", "SSLv3" }, 196 new String[] { "TLSv1", "SSLv3" }, 197 false, "TLSv1"); 198 runCase(new String[] { "TLSv1", "SSLv3" }, 199 new String[] { "SSLv3", "SSLv2Hello" }, 200 true, null); 201 runCase(new String[] { "TLSv1", "SSLv3" }, 202 new String[] { "SSLv3" }, 203 false, "SSLv3"); 204 runCase(new String[] { "TLSv1", "SSLv3" }, 205 new String[] { "TLSv1", "SSLv3", "SSLv2Hello" }, 206 true, null); 207 208 runCase(new String[] { "SSLv3", "SSLv2Hello" }, 209 new String[] { "TLSv1" }, 210 true, null); 211 runCase(new String[] { "SSLv3", "SSLv2Hello" }, 212 new String[] { "TLSv1", "SSLv2Hello" }, 213 true, null); 214 runCase(new String[] { "SSLv3", "SSLv2Hello" }, 215 new String[] { "TLSv1", "SSLv3" }, 216 false, "SSLv3"); 217 runCase(new String[] { "SSLv3", "SSLv2Hello" }, 218 new String[] { "SSLv3", "SSLv2Hello" }, 219 false, "SSLv3"); 220 runCase(new String[] { "SSLv3", "SSLv2Hello" }, 221 new String[] { "SSLv3" }, 222 false, "SSLv3"); 223 runCase(new String[] { "SSLv3", "SSLv2Hello" }, 224 new String[] { "TLSv1", "SSLv3", "SSLv2Hello" }, 225 false, "SSLv3"); 226 227 runCase(new String[] { "SSLv3" }, 228 new String[] { "TLSv1" }, 229 true, null); 230 runCase(new String[] { "SSLv3" }, 231 new String[] { "TLSv1", "SSLv2Hello" }, 232 true, null); 233 runCase(new String[] { "SSLv3" }, 234 new String[] { "TLSv1", "SSLv3" }, 235 false, "SSLv3"); 236 runCase(new String[] { "SSLv3" }, 237 new String[] { "SSLv3", "SSLv2Hello" }, 238 true, null); 239 runCase(new String[] { "SSLv3" }, 240 new String[] { "SSLv3" }, 241 false, "SSLv3"); 242 runCase(new String[] { "SSLv3" }, 243 new String[] { "TLSv1", "SSLv3", "SSLv2Hello" }, 244 true, null); 245 246 runCase(new String[] { "TLSv1", "SSLv3", "SSLv2Hello" }, 247 new String[] { "TLSv1" }, 248 false, "TLSv1"); 249 runCase(new String[] { "TLSv1", "SSLv3", "SSLv2Hello" }, 250 new String[] { "TLSv1", "SSLv2Hello" }, 251 false, "TLSv1"); 252 runCase(new String[] { "TLSv1", "SSLv3", "SSLv2Hello" }, 253 new String[] { "TLSv1", "SSLv3" }, 254 false, "TLSv1"); 255 runCase(new String[] { "TLSv1", "SSLv3", "SSLv2Hello" }, 256 new String[] { "SSLv3", "SSLv2Hello" }, 257 false, "SSLv3"); 258 runCase(new String[] { "TLSv1", "SSLv3", "SSLv2Hello" }, 259 new String[] { "SSLv3" }, 260 false, "SSLv3"); 261 runCase(new String[] { "TLSv1", "SSLv3", "SSLv2Hello" }, 262 new String[] { "TLSv1", "SSLv3", "SSLv2Hello" }, 263 false, "TLSv1"); 264 } 265 runCase( String[] serverProtocols, String[] clientProtocols, boolean exceptionExpected, String selectedProtocol)266 private static void runCase( 267 String[] serverProtocols, 268 String[] clientProtocols, 269 boolean exceptionExpected, 270 String selectedProtocol) throws Exception { 271 new TestEnabledProtocols( 272 serverProtocols, 273 clientProtocols, 274 exceptionExpected, 275 selectedProtocol).run(); 276 } 277 showProtocols(String name, String[] protocols)278 private static void showProtocols(String name, String[] protocols) { 279 System.out.printf("Enabled protocols on the %s are: %s%n", 280 name, 281 Arrays.asList(protocols)); 282 } 283 } 284