1 /*
2 * Copyright (c) 2004, 2011, 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 * @test
26 * @bug 4495742
27 * @summary Add non-blocking SSL/TLS functionality, usable with any
28 * I/O abstraction
29 *
30 * This is to test larger buffer arrays, and make sure the maximum
31 * is being passed.
32 *
33 * @run main/othervm -Djsse.enableCBCProtection=false LargeBufs
34 *
35 * @author Brad R. Wetmore
36 */
37
38 import javax.net.ssl.*;
39 import javax.net.ssl.SSLEngineResult.*;
40 import java.io.*;
41 import java.security.*;
42 import java.nio.*;
43 import java.util.Random;
44
45 public class LargeBufs {
46
47 private static boolean debug = false;
48
49 private SSLContext sslc;
50 static private SSLEngine ssle1; // client
51 static private SSLEngine ssle2; // server
52
53 private static String pathToStores = "../../../../../etc";
54 private static String keyStoreFile = "keystore";
55 private static String trustStoreFile = "truststore";
56 private static String passwd = "passphrase";
57
58 private static String keyFilename =
59 System.getProperty("test.src", "./") + "/" + pathToStores +
60 "/" + keyStoreFile;
61 private static String trustFilename =
62 System.getProperty("test.src", "./") + "/" + pathToStores +
63 "/" + trustStoreFile;
64
65 private ByteBuffer appOut1; // write side of ssle1
66 private ByteBuffer appIn1; // read side of ssle1
67 private ByteBuffer appOut2; // write side of ssle2
68 private ByteBuffer appIn2; // read side of ssle2
69
70 private ByteBuffer oneToTwo; // "reliable" transport ssle1->ssle2
71 private ByteBuffer twoToOne; // "reliable" transport ssle2->ssle1
72
73 private int appBufferMax;
74 private int netBufferMax;
75 private int OFFSET = 37;
76
77 /*
78 * Majority of the test case is here, setup is done below.
79 */
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
89 private void runTest(String cipher) throws Exception {
90 boolean dataDone = false;
91
92 createSSLEngines();
93
94 System.out.println("Using " + cipher);
95 ssle2.setEnabledCipherSuites(new String [] { cipher });
96
97 createBuffers();
98
99 SSLEngineResult result1; // ssle1's results from last operation
100 SSLEngineResult result2; // ssle2's results from last operation
101
102 while (!isEngineClosed(ssle1) || !isEngineClosed(ssle2)) {
103
104 log("================");
105
106 result1 = ssle1.wrap(appOut1, oneToTwo);
107 result2 = ssle2.wrap(appOut2, twoToOne);
108
109 if ((result1.bytesConsumed() != 0) &&
110 (result1.bytesConsumed() != appBufferMax) &&
111 (result1.bytesConsumed() != OFFSET)) {
112 throw new Exception("result1: " + result1);
113 }
114
115 if ((result2.bytesConsumed() != 0) &&
116 (result2.bytesConsumed() != appBufferMax) &&
117 (result2.bytesConsumed() != 2 * OFFSET)) {
118 throw new Exception("result1: " + result1);
119 }
120
121 log("wrap1: " + result1);
122 log("oneToTwo = " + oneToTwo);
123 log("");
124
125 log("wrap2: " + result2);
126 log("twoToOne = " + twoToOne);
127
128 runDelegatedTasks(result1, ssle1);
129 runDelegatedTasks(result2, ssle2);
130
131 oneToTwo.flip();
132 twoToOne.flip();
133
134 log("----");
135
136 result1 = ssle1.unwrap(twoToOne, appIn1);
137 result2 = ssle2.unwrap(oneToTwo, appIn2);
138
139 if ((result1.bytesProduced() != 0) &&
140 (result1.bytesProduced() != appBufferMax) &&
141 (result1.bytesProduced() != 2 * OFFSET)) {
142 throw new Exception("result1: " + result1);
143 }
144
145 if ((result2.bytesProduced() != 0) &&
146 (result2.bytesProduced() != appBufferMax) &&
147 (result2.bytesProduced() != OFFSET)) {
148 throw new Exception("result1: " + result1);
149 }
150
151 log("unwrap1: " + result1);
152 log("twoToOne = " + twoToOne);
153 log("");
154
155 log("unwrap2: " + result2);
156 log("oneToTwo = " + oneToTwo);
157
158 runDelegatedTasks(result1, ssle1);
159 runDelegatedTasks(result2, ssle2);
160
161 oneToTwo.compact();
162 twoToOne.compact();
163
164 /*
165 * If we've transfered all the data between app1 and app2,
166 * we try to close and see what that gets us.
167 */
168 if (!dataDone && (appOut1.limit() == appIn2.position()) &&
169 (appOut2.limit() == appIn1.position())) {
170
171 checkTransfer(appOut1, appIn2);
172 checkTransfer(appOut2, appIn1);
173
174 log("Closing ssle1's *OUTBOUND*...");
175 ssle1.closeOutbound();
176 dataDone = true;
177 }
178 }
179 }
180
181 public static void main(String args[]) throws Exception {
182
183 LargeBufs test;
184
185 test = new LargeBufs();
186 test.runTest("SSL_RSA_WITH_RC4_128_MD5");
187
188 test = new LargeBufs();
189 test.runTest("SSL_RSA_WITH_3DES_EDE_CBC_SHA");
190
191 System.out.println("Test Passed.");
192 }
193
194 /*
195 * **********************************************************
196 * Majority of the test case is above, below is just setup stuff
197 * **********************************************************
198 */
199
200 public LargeBufs() throws Exception {
201 sslc = getSSLContext(keyFilename, trustFilename);
202 }
203
204 /*
205 * Create an initialized SSLContext to use for this test.
206 */
207 private SSLContext getSSLContext(String keyFile, String trustFile)
208 throws Exception {
209
210 KeyStore ks = KeyStore.getInstance("JKS");
211 KeyStore ts = KeyStore.getInstance("JKS");
212
213 char[] passphrase = "passphrase".toCharArray();
214
215 ks.load(new FileInputStream(keyFile), passphrase);
216 ts.load(new FileInputStream(trustFile), passphrase);
217
218 KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
219 kmf.init(ks, passphrase);
220
221 TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
222 tmf.init(ts);
223
224 SSLContext sslCtx = SSLContext.getInstance("TLS");
225
226 sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
227
228 return sslCtx;
229 }
230
231 private void createBuffers() {
232 // Size the buffers as appropriate.
233
234 SSLSession session = ssle1.getSession();
235
236 // The maximum application buffer should calculate like
237 // appBufferMax = session.getApplicationBufferSize();
238 // however, the getApplicationBufferSize() doesn't guarantee
239 // that the ability to concume or produce applicaton data upto
240 // the size. 16384 is the default JSSE implementation maximum
241 // application size that could be consumed and produced.
242 appBufferMax = 16384;
243 netBufferMax = session.getPacketBufferSize();
244
245 Random random = new Random();
246 byte [] one = new byte [appBufferMax * 5 + OFFSET];
247 byte [] two = new byte [appBufferMax * 5 + 2 * OFFSET];
248
249 random.nextBytes(one);
250 random.nextBytes(two);
251
252 appOut1 = ByteBuffer.wrap(one);
253 appOut2 = ByteBuffer.wrap(two);
254
255 appIn1 = ByteBuffer.allocate(appBufferMax * 6);
256 appIn2 = ByteBuffer.allocate(appBufferMax * 6);
257
258 oneToTwo = ByteBuffer.allocateDirect(netBufferMax);
259 twoToOne = ByteBuffer.allocateDirect(netBufferMax);
260
261 System.out.println("Testing arrays of: " + one.length +
262 " and " + two.length);
263
264 log("AppOut1 = " + appOut1);
265 log("AppOut2 = " + appOut2);
266 log("");
267 }
268
269 private static void runDelegatedTasks(SSLEngineResult result,
270 SSLEngine engine) throws Exception {
271
272 if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
273 Runnable runnable;
274 while ((runnable = engine.getDelegatedTask()) != null) {
275 log("running delegated task...");
276 runnable.run();
277 }
278 }
279 }
280
281 private static boolean isEngineClosed(SSLEngine engine) {
282 return (engine.isOutboundDone() && engine.isInboundDone());
283 }
284
285 private static void checkTransfer(ByteBuffer a, ByteBuffer b)
286 throws Exception {
287 a.flip();
288 b.flip();
289
290 if (!a.equals(b)) {
291 throw new Exception("Data didn't transfer cleanly");
292 } else {
293 log("Data transferred cleanly");
294 }
295 }
296
297 private static void log(String str) {
298 if (debug) {
299 System.out.println(str);
300 }
301 }
302 }
--- EOF ---