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