1 /* 2 * Copyright (c) 2003, 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 // 25 // SunJSSE does not support dynamic system properties, no way to re-use 26 // system properties in samevm/agentvm mode. 27 // 28 29 /* 30 * @test 31 * @bug 4969799 32 * @summary javax.net.ssl.SSLSocket.SSLSocket(InetAddress,int) shouldn't 33 * throw exception 34 * @run main/othervm CloseEngineException 35 */ 36 37 // 38 // This is making sure that starting a new handshake throws the right 39 // exception. There is a similar test for SSLSocket. 40 // 41 42 import javax.net.ssl.*; 43 import javax.net.ssl.SSLEngineResult.*; 44 import java.io.*; 45 import java.security.*; 46 import java.nio.*; 47 48 // Note that this test case depends on JSSE provider implementation details. 49 public class CloseEngineException { 50 51 private static boolean debug = true; 52 53 private SSLContext sslc; 54 private SSLEngine ssle1; // client 55 private SSLEngine ssle2; // server 56 57 private static String pathToStores = "../../../../javax/net/ssl/etc"; 58 private static String keyStoreFile = "keystore"; 59 private static String trustStoreFile = "truststore"; 60 private static String passwd = "passphrase"; 61 62 private static String keyFilename = 63 System.getProperty("test.src", "./") + "/" + pathToStores + 64 "/" + keyStoreFile; 65 private static String trustFilename = 66 System.getProperty("test.src", "./") + "/" + pathToStores + 67 "/" + trustStoreFile; 68 69 private ByteBuffer appOut1; // write side of ssle1 70 private ByteBuffer appIn1; // read side of ssle1 71 private ByteBuffer appOut2; // write side of ssle2 72 private ByteBuffer appIn2; // read side of ssle2 73 74 private ByteBuffer oneToTwo; // "reliable" transport ssle1->ssle2 75 private ByteBuffer twoToOne; // "reliable" transport ssle2->ssle1 76 77 /* 78 * Majority of the test case is here, setup is done below. 79 */ createSSLEngines()80 private void createSSLEngines() throws Exception { 81 ssle1 = sslc.createSSLEngine("client", 1); 82 ssle1.setUseClientMode(true); 83 84 ssle2 = sslc.createSSLEngine(); 85 ssle2.setUseClientMode(false); 86 ssle2.setNeedClientAuth(true); 87 } 88 runTest()89 private void runTest() throws Exception { 90 boolean dataDone = false; 91 92 createSSLEngines(); 93 createBuffers(); 94 95 SSLEngineResult result1; // ssle1's results from last operation 96 SSLEngineResult result2; // ssle2's results from last operation 97 98 while (!isEngineClosed(ssle1) && !isEngineClosed(ssle2)) { 99 100 log("================"); 101 102 if (!isEngineClosed(ssle1)) { 103 result1 = ssle1.wrap(appOut1, oneToTwo); 104 runDelegatedTasks(result1, ssle1); 105 106 log("wrap1: " + result1); 107 log("oneToTwo = " + oneToTwo); 108 log(""); 109 110 oneToTwo.flip(); 111 } 112 if (!isEngineClosed(ssle2)) { 113 result2 = ssle2.wrap(appOut2, twoToOne); 114 runDelegatedTasks(result2, ssle2); 115 116 log("wrap2: " + result2); 117 log("twoToOne = " + twoToOne); 118 119 twoToOne.flip(); 120 } 121 122 log("----"); 123 124 if (!isEngineClosed(ssle1) && !dataDone) { 125 log("--"); 126 result1 = ssle1.unwrap(twoToOne, appIn1); 127 runDelegatedTasks(result1, ssle1); 128 129 log("unwrap1: " + result1); 130 log("twoToOne = " + twoToOne); 131 log(""); 132 133 twoToOne.compact(); 134 } 135 if (!isEngineClosed(ssle2)) { 136 log("---"); 137 result2 = ssle2.unwrap(oneToTwo, appIn2); 138 runDelegatedTasks(result2, ssle2); 139 140 log("unwrap2: " + result2); 141 log("oneToTwo = " + oneToTwo); 142 143 oneToTwo.compact(); 144 } 145 146 /* 147 * If we've transfered all the data between app1 and app2, 148 * we try to close and see what that gets us. 149 */ 150 if (!dataDone && (appOut1.limit() == appIn2.position()) && 151 (appOut2.limit() == appIn1.position())) { 152 153 checkTransfer(appOut1, appIn2); 154 checkTransfer(appOut2, appIn1); 155 156 log("Closing ssle1's *OUTBOUND*..."); 157 ssle1.closeOutbound(); 158 dataDone = true; 159 160 try { 161 /* 162 * Check that closed Outbound generates. 163 */ 164 ssle1.beginHandshake(); 165 throw new Exception( 166 "TEST FAILED: didn't throw Exception"); 167 } catch (SSLException e) { 168 System.err.println("PARTIAL PASS"); 169 } 170 } 171 } 172 173 try { 174 /* 175 * Check that closed Inbound generates. 176 */ 177 ssle2.beginHandshake(); 178 throw new Exception( 179 "TEST FAILED: didn't throw Exception"); 180 } catch (SSLException e) { 181 System.err.println("TEST PASSED"); 182 } 183 } 184 main(String args[])185 public static void main(String args[]) throws Exception { 186 187 CloseEngineException test; 188 189 test = new CloseEngineException(); 190 191 test.createSSLEngines(); 192 193 test.runTest(); 194 195 System.err.println("Test Passed."); 196 } 197 198 /* 199 * ********************************************************** 200 * Majority of the test case is above, below is just setup stuff 201 * ********************************************************** 202 */ 203 CloseEngineException()204 public CloseEngineException() throws Exception { 205 sslc = getSSLContext(keyFilename, trustFilename); 206 } 207 208 /* 209 * Create an initialized SSLContext to use for this test. 210 */ getSSLContext(String keyFile, String trustFile)211 private SSLContext getSSLContext(String keyFile, String trustFile) 212 throws Exception { 213 214 KeyStore ks = KeyStore.getInstance("JKS"); 215 KeyStore ts = KeyStore.getInstance("JKS"); 216 217 char[] passphrase = "passphrase".toCharArray(); 218 219 ks.load(new FileInputStream(keyFile), passphrase); 220 ts.load(new FileInputStream(trustFile), passphrase); 221 222 KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 223 kmf.init(ks, passphrase); 224 225 TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); 226 tmf.init(ts); 227 228 SSLContext sslCtx = SSLContext.getInstance("TLS"); 229 230 sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 231 232 return sslCtx; 233 } 234 createBuffers()235 private void createBuffers() { 236 // Size the buffers as appropriate. 237 238 SSLSession session = ssle1.getSession(); 239 int appBufferMax = session.getApplicationBufferSize(); 240 int netBufferMax = session.getPacketBufferSize(); 241 242 appIn1 = ByteBuffer.allocateDirect(appBufferMax + 50); 243 appIn2 = ByteBuffer.allocateDirect(appBufferMax + 50); 244 245 oneToTwo = ByteBuffer.allocateDirect(netBufferMax); 246 twoToOne = ByteBuffer.allocateDirect(netBufferMax); 247 248 appOut1 = ByteBuffer.wrap("Hi Engine2, I'm SSLEngine1".getBytes()); 249 appOut2 = ByteBuffer.wrap("Hello Engine1, I'm SSLEngine2".getBytes()); 250 251 log("AppOut1 = " + appOut1); 252 log("AppOut2 = " + appOut2); 253 log(""); 254 } 255 runDelegatedTasks(SSLEngineResult result, SSLEngine engine)256 private static void runDelegatedTasks(SSLEngineResult result, 257 SSLEngine engine) throws Exception { 258 259 if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { 260 Runnable runnable; 261 while ((runnable = engine.getDelegatedTask()) != null) { 262 log("running delegated task..."); 263 runnable.run(); 264 } 265 } 266 } 267 isEngineClosed(SSLEngine engine)268 private static boolean isEngineClosed(SSLEngine engine) { 269 return (engine.isOutboundDone() && engine.isInboundDone()); 270 } 271 checkTransfer(ByteBuffer a, ByteBuffer b)272 private static void checkTransfer(ByteBuffer a, ByteBuffer b) 273 throws Exception { 274 a.flip(); 275 b.flip(); 276 277 if (!a.equals(b)) { 278 throw new Exception("Data didn't transfer cleanly"); 279 } else { 280 log("Data transferred cleanly"); 281 } 282 283 a.position(a.limit()); 284 b.position(b.limit()); 285 a.limit(a.capacity()); 286 b.limit(b.capacity()); 287 } 288 log(String str)289 private static void log(String str) { 290 if (debug) { 291 System.err.println(str); 292 } 293 } 294 } 295