1 /* 2 * Copyright (c) 2010, 2020, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * @test 28 * @bug 4873188 29 * @summary Support TLS 1.1 30 * @library /test/lib 31 * @modules java.security.jgss 32 * java.security.jgss/sun.security.jgss.krb5 33 * java.security.jgss/sun.security.krb5:+open 34 * java.security.jgss/sun.security.krb5.internal:+open 35 * java.security.jgss/sun.security.krb5.internal.ccache 36 * java.security.jgss/sun.security.krb5.internal.crypto 37 * java.security.jgss/sun.security.krb5.internal.ktab 38 * java.base/sun.security.util 39 * @run main/othervm GenericBlockCipher 40 * 41 * SunJSSE does not support dynamic system properties, no way to re-use 42 * system properties in samevm/agentvm mode. 43 * 44 * @author Xuelei Fan 45 */ 46 47 import java.io.InputStream; 48 import java.io.OutputStream; 49 import javax.net.ssl.SSLServerSocket; 50 import javax.net.ssl.SSLServerSocketFactory; 51 import javax.net.ssl.SSLSocket; 52 import javax.net.ssl.SSLSocketFactory; 53 54 import jdk.test.lib.security.SecurityUtils; 55 56 public class GenericBlockCipher { 57 58 /* 59 * ============================================================= 60 * Set the various variables needed for the tests, then 61 * specify what tests to run on each side. 62 */ 63 64 /* 65 * Should we run the client or server in a separate thread? 66 * Both sides can throw exceptions, but do you have a preference 67 * as to which side should be the main thread. 68 */ 69 static boolean separateServerThread = false; 70 71 /* 72 * Where do we find the keystores? 73 */ 74 static String pathToStores = "../etc"; 75 static String keyStoreFile = "keystore"; 76 static String trustStoreFile = "truststore"; 77 static String passwd = "passphrase"; 78 79 /* 80 * Is the server ready to serve? 81 */ 82 volatile static boolean serverReady = false; 83 84 /* 85 * Turn on SSL debugging? 86 */ 87 static boolean debug = false; 88 89 /* 90 * If the client or server is doing some kind of object creation 91 * that the other side depends on, and that thread prematurely 92 * exits, you may experience a hang. The test harness will 93 * terminate all hung threads after its timeout has expired, 94 * currently 3 minutes by default, but you might try to be 95 * smart about it.... 96 */ 97 98 /* 99 * Define the server side of the test. 100 * 101 * If the server prematurely exits, serverReady will be set to true 102 * to avoid infinite hangs. 103 */ doServerSide()104 void doServerSide() throws Exception { 105 SSLServerSocketFactory sslssf = 106 (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); 107 SSLServerSocket sslServerSocket = 108 (SSLServerSocket) sslssf.createServerSocket(serverPort); 109 110 serverPort = sslServerSocket.getLocalPort(); 111 112 /* 113 * Signal Client, we're ready for his connect. 114 */ 115 serverReady = true; 116 117 SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); 118 InputStream sslIS = sslSocket.getInputStream(); 119 OutputStream sslOS = sslSocket.getOutputStream(); 120 121 sslIS.read(); 122 sslOS.write('A'); 123 sslOS.flush(); 124 125 sslSocket.close(); 126 } 127 128 /* 129 * Define the client side of the test. 130 * 131 * If the server prematurely exits, serverReady will be set to true 132 * to avoid infinite hangs. 133 */ doClientSide()134 void doClientSide() throws Exception { 135 136 /* 137 * Wait for server to get started. 138 */ 139 while (!serverReady) { 140 Thread.sleep(50); 141 } 142 143 SSLSocketFactory sslsf = 144 (SSLSocketFactory) SSLSocketFactory.getDefault(); 145 SSLSocket sslSocket = (SSLSocket) 146 sslsf.createSocket("localhost", serverPort); 147 148 // enable TLSv1.1 only 149 sslSocket.setEnabledProtocols(new String[] {"TLSv1.1"}); 150 151 // enable a block cipher 152 sslSocket.setEnabledCipherSuites( 153 new String[] {"TLS_RSA_WITH_AES_128_CBC_SHA"}); 154 155 InputStream sslIS = sslSocket.getInputStream(); 156 OutputStream sslOS = sslSocket.getOutputStream(); 157 158 sslOS.write('B'); 159 sslOS.flush(); 160 sslIS.read(); 161 162 sslSocket.close(); 163 } 164 165 /* 166 * ============================================================= 167 * The remainder is just support stuff 168 */ 169 170 // use any free port by default 171 volatile int serverPort = 0; 172 173 volatile Exception serverException = null; 174 volatile Exception clientException = null; 175 main(String[] args)176 public static void main(String[] args) throws Exception { 177 // Re-enable TLSv1.1 since test depends on it. 178 SecurityUtils.removeFromDisabledTlsAlgs("TLSv1.1"); 179 180 String keyFilename = 181 System.getProperty("test.src", ".") + "/" + pathToStores + 182 "/" + keyStoreFile; 183 String trustFilename = 184 System.getProperty("test.src", ".") + "/" + pathToStores + 185 "/" + trustStoreFile; 186 187 System.setProperty("javax.net.ssl.keyStore", keyFilename); 188 System.setProperty("javax.net.ssl.keyStorePassword", passwd); 189 System.setProperty("javax.net.ssl.trustStore", trustFilename); 190 System.setProperty("javax.net.ssl.trustStorePassword", passwd); 191 192 if (debug) 193 System.setProperty("javax.net.debug", "all"); 194 195 /* 196 * Start the tests. 197 */ 198 new GenericBlockCipher(); 199 } 200 201 Thread clientThread = null; 202 Thread serverThread = null; 203 204 /* 205 * Primary constructor, used to drive remainder of the test. 206 * 207 * Fork off the other side, then do your work. 208 */ GenericBlockCipher()209 GenericBlockCipher() throws Exception { 210 try { 211 if (separateServerThread) { 212 startServer(true); 213 startClient(false); 214 } else { 215 startClient(true); 216 startServer(false); 217 } 218 } catch (Exception e) { 219 // swallow for now. Show later 220 } 221 222 /* 223 * Wait for other side to close down. 224 */ 225 if (separateServerThread) { 226 serverThread.join(); 227 } else { 228 clientThread.join(); 229 } 230 231 /* 232 * When we get here, the test is pretty much over. 233 * Which side threw the error? 234 */ 235 Exception local; 236 Exception remote; 237 String whichRemote; 238 239 if (separateServerThread) { 240 remote = serverException; 241 local = clientException; 242 whichRemote = "server"; 243 } else { 244 remote = clientException; 245 local = serverException; 246 whichRemote = "client"; 247 } 248 249 /* 250 * If both failed, return the curthread's exception, but also 251 * print the remote side Exception 252 */ 253 if ((local != null) && (remote != null)) { 254 System.out.println(whichRemote + " also threw:"); 255 remote.printStackTrace(); 256 System.out.println(); 257 throw local; 258 } 259 260 if (remote != null) { 261 throw remote; 262 } 263 264 if (local != null) { 265 throw local; 266 } 267 } 268 startServer(boolean newThread)269 void startServer(boolean newThread) throws Exception { 270 if (newThread) { 271 serverThread = new Thread() { 272 public void run() { 273 try { 274 doServerSide(); 275 } catch (Exception e) { 276 /* 277 * Our server thread just died. 278 * 279 * Release the client, if not active already... 280 */ 281 System.err.println("Server died..."); 282 serverReady = true; 283 serverException = e; 284 } 285 } 286 }; 287 serverThread.start(); 288 } else { 289 try { 290 doServerSide(); 291 } catch (Exception e) { 292 serverException = e; 293 } finally { 294 serverReady = true; 295 } 296 } 297 } 298 startClient(boolean newThread)299 void startClient(boolean newThread) throws Exception { 300 if (newThread) { 301 clientThread = new Thread() { 302 public void run() { 303 try { 304 doClientSide(); 305 } catch (Exception e) { 306 /* 307 * Our client thread just died. 308 */ 309 System.err.println("Client died..."); 310 clientException = e; 311 } 312 } 313 }; 314 clientThread.start(); 315 } else { 316 try { 317 doClientSide(); 318 } catch (Exception e) { 319 clientException = e; 320 } 321 } 322 } 323 } 324