Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/net/ssl/SSLEngine/FinishedPresent.java
41152 views
1
/*
2
* Copyright (c) 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.
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 8233619
30
* @summary SSLEngine has not yet caused Solaris kernel to panic
31
* @run main/othervm FinishedPresent
32
*/
33
import javax.net.ssl.*;
34
import javax.net.ssl.SSLEngineResult.*;
35
import java.io.*;
36
import java.security.*;
37
import java.nio.*;
38
39
public class FinishedPresent {
40
41
/*
42
* Enables logging of the SSLEngine operations.
43
*/
44
private static final boolean logging = true;
45
46
/*
47
* Enables the JSSE system debugging system property:
48
*
49
* -Djavax.net.debug=all
50
*
51
* This gives a lot of low-level information about operations underway,
52
* including specific handshake messages, and might be best examined
53
* after gaining some familiarity with this application.
54
*/
55
private static final boolean debug = false;
56
57
private final SSLContext sslc;
58
59
private SSLEngine clientEngine; // client Engine
60
private ByteBuffer clientOut; // write side of clientEngine
61
private ByteBuffer clientIn; // read side of clientEngine
62
63
private SSLEngine serverEngine; // server Engine
64
private ByteBuffer serverOut; // write side of serverEngine
65
private ByteBuffer serverIn; // read side of serverEngine
66
67
/*
68
* For data transport, this example uses local ByteBuffers. This
69
* isn't really useful, but the purpose of this example is to show
70
* SSLEngine concepts, not how to do network transport.
71
*/
72
private ByteBuffer cTOs; // "reliable" transport client->server
73
private ByteBuffer sTOc; // "reliable" transport server->client
74
75
/*
76
* The following is to set up the keystores.
77
*/
78
private static final String pathToStores = "../etc";
79
private static final String keyStoreFile = "keystore";
80
private static final String trustStoreFile = "truststore";
81
private static final char[] passphrase = "passphrase".toCharArray();
82
83
private static final String keyFilename =
84
System.getProperty("test.src", ".") + "/" + pathToStores +
85
"/" + keyStoreFile;
86
private static final String trustFilename =
87
System.getProperty("test.src", ".") + "/" + pathToStores +
88
"/" + trustStoreFile;
89
90
/*
91
* Main entry point for this test.
92
*/
93
public static void main(String args[]) throws Exception {
94
if (debug) {
95
System.setProperty("javax.net.debug", "all");
96
}
97
98
FinishedPresent test = new FinishedPresent();
99
test.runTest();
100
101
log("Test Passed.");
102
}
103
104
/*
105
* Create an initialized SSLContext to use for these tests.
106
*/
107
public FinishedPresent() throws Exception {
108
109
KeyStore ks = KeyStore.getInstance("JKS");
110
KeyStore ts = KeyStore.getInstance("JKS");
111
112
ks.load(new FileInputStream(keyFilename), passphrase);
113
ts.load(new FileInputStream(trustFilename), passphrase);
114
115
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
116
kmf.init(ks, passphrase);
117
118
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
119
tmf.init(ts);
120
121
SSLContext sslCtx = SSLContext.getInstance("TLSv1.3");
122
123
sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
124
125
sslc = sslCtx;
126
}
127
128
/*
129
* Run the test.
130
*
131
* Sit in a tight loop, both engines calling wrap/unwrap regardless
132
* of whether data is available or not. We do this until both engines
133
* report back they are closed.
134
*
135
* The main loop handles all of the I/O phases of the SSLEngine's
136
* lifetime:
137
*
138
* initial handshaking
139
* application data transfer
140
* engine closing
141
*
142
* One could easily separate these phases into separate
143
* sections of code.
144
*/
145
private void runTest() throws Exception {
146
boolean dataDone = false;
147
148
createSSLEngines();
149
createBuffers();
150
151
// results from client's last operation
152
SSLEngineResult clientResult;
153
154
// results from server's last operation
155
SSLEngineResult serverResult;
156
157
/*
158
* Examining the SSLEngineResults could be much more involved,
159
* and may alter the overall flow of the application.
160
*
161
* For example, if we received a BUFFER_OVERFLOW when trying
162
* to write to the output pipe, we could reallocate a larger
163
* pipe, but instead we wait for the peer to drain it.
164
*/
165
Exception clientException = null;
166
Exception serverException = null;
167
168
boolean clientFinishedPresent = false;
169
boolean serverFinishedPresent = false;
170
boolean client2ndFinishedPresent = false;
171
boolean server2ndFinishedPresent = false;
172
while (!isEngineClosed(clientEngine)
173
|| !isEngineClosed(serverEngine)) {
174
175
log("================");
176
177
try {
178
clientResult = clientEngine.wrap(clientOut, cTOs);
179
if (clientFinishedPresent) {
180
client2ndFinishedPresent |= hasFinished(
181
"posthandshake client wrap", clientResult);
182
} else {
183
clientFinishedPresent |= hasFinished(
184
"client wrap", clientResult);
185
}
186
log("client wrap: ", clientResult);
187
} catch (Exception e) {
188
clientException = e;
189
log("Client wrap() threw: " + e.getMessage());
190
}
191
logEngineStatus(clientEngine);
192
runDelegatedTasks(clientEngine);
193
194
log("----");
195
196
try {
197
serverResult = serverEngine.wrap(serverOut, sTOc);
198
if (serverFinishedPresent) {
199
server2ndFinishedPresent |= hasFinished(
200
"posthandshake server wrap", serverResult);
201
} else {
202
serverFinishedPresent |= hasFinished(
203
"server wrap", serverResult);
204
}
205
log("server wrap: ", serverResult);
206
} catch (Exception e) {
207
serverException = e;
208
log("Server wrap() threw: " + e.getMessage());
209
}
210
logEngineStatus(serverEngine);
211
runDelegatedTasks(serverEngine);
212
213
cTOs.flip();
214
sTOc.flip();
215
216
log("--------");
217
218
try {
219
clientResult = clientEngine.unwrap(sTOc, clientIn);
220
if (clientFinishedPresent) {
221
client2ndFinishedPresent |= hasFinished(
222
"posthandshake client unwrap", clientResult);
223
} else {
224
clientFinishedPresent |= hasFinished(
225
"client unwrap", clientResult);
226
}
227
log("client unwrap: ", clientResult);
228
} catch (Exception e) {
229
clientException = e;
230
log("Client unwrap() threw: " + e.getMessage());
231
}
232
logEngineStatus(clientEngine);
233
runDelegatedTasks(clientEngine);
234
235
log("----");
236
237
try {
238
serverResult = serverEngine.unwrap(cTOs, serverIn);
239
if (serverFinishedPresent) {
240
server2ndFinishedPresent |= hasFinished(
241
"posthandshake server unwrap", serverResult);
242
} else {
243
serverFinishedPresent |= hasFinished(
244
"server unwrap", serverResult);
245
}
246
log("server unwrap: ", serverResult);
247
} catch (Exception e) {
248
serverException = e;
249
log("Server unwrap() threw: " + e.getMessage());
250
}
251
logEngineStatus(serverEngine);
252
runDelegatedTasks(serverEngine);
253
254
cTOs.compact();
255
sTOc.compact();
256
257
/*
258
* After we've transfered all application data between the client
259
* and server, we close the clientEngine's outbound stream.
260
* This generates a close_notify handshake message, which the
261
* server engine receives and responds by closing itself.
262
*/
263
if (!dataDone && (clientOut.limit() == serverIn.position()) &&
264
(serverOut.limit() == clientIn.position())) {
265
266
/*
267
* A sanity check to ensure we got what was sent.
268
*/
269
checkTransfer(serverOut, clientIn);
270
checkTransfer(clientOut, serverIn);
271
272
log("\tClosing clientEngine's *OUTBOUND*...");
273
clientEngine.closeOutbound();
274
logEngineStatus(clientEngine);
275
276
dataDone = true;
277
log("\tClosing serverEngine's *OUTBOUND*...");
278
serverEngine.closeOutbound();
279
logEngineStatus(serverEngine);
280
}
281
}
282
283
if (!clientFinishedPresent) {
284
throw new Exception("No client FINISHED status present");
285
}
286
287
if (!serverFinishedPresent) {
288
throw new Exception("No server FINISHED status present");
289
}
290
291
if (!client2ndFinishedPresent) {
292
throw new Exception(
293
"No posthandshake client FINISHED status present");
294
}
295
296
// Note: the server side did not finish the handshake unless the
297
// posthandshake message get delivered. This behaviro may be
298
// updated in the future.
299
//
300
// if (!server2ndFinishedPresent) {
301
// throw new Exception(
302
// "No posthandshake server FINISHED status present");
303
// }
304
}
305
306
private static void logEngineStatus(SSLEngine engine) {
307
log("\tCurrent HS State " + engine.getHandshakeStatus().toString());
308
log("\tisInboundDone(): " + engine.isInboundDone());
309
log("\tisOutboundDone(): " + engine.isOutboundDone());
310
}
311
312
private static boolean hasFinished(
313
String prefix, SSLEngineResult engineResult) {
314
if (engineResult.getHandshakeStatus() == HandshakeStatus.FINISHED) {
315
log(prefix + " finished present: " + engineResult);
316
return true;
317
}
318
319
return false;
320
}
321
322
/*
323
* Using the SSLContext created during object creation,
324
* create/configure the SSLEngines we'll use for this test.
325
*/
326
private void createSSLEngines() throws Exception {
327
/*
328
* Configure the serverEngine to act as a server in the SSL/TLS
329
* handshake. Also, require SSL client authentication.
330
*/
331
serverEngine = sslc.createSSLEngine();
332
serverEngine.setUseClientMode(false);
333
serverEngine.setNeedClientAuth(true);
334
335
// Get/set parameters if needed
336
SSLParameters paramsServer = serverEngine.getSSLParameters();
337
serverEngine.setSSLParameters(paramsServer);
338
339
/*
340
* Similar to above, but using client mode instead.
341
*/
342
clientEngine = sslc.createSSLEngine("client", 80);
343
clientEngine.setUseClientMode(true);
344
345
// Get/set parameters if needed
346
SSLParameters paramsClient = clientEngine.getSSLParameters();
347
clientEngine.setSSLParameters(paramsClient);
348
}
349
350
/*
351
* Create and size the buffers appropriately.
352
*/
353
private void createBuffers() {
354
355
/*
356
* We'll assume the buffer sizes are the same
357
* between client and server.
358
*/
359
SSLSession session = clientEngine.getSession();
360
int appBufferMax = session.getApplicationBufferSize();
361
int netBufferMax = session.getPacketBufferSize();
362
363
/*
364
* We'll make the input buffers a bit bigger than the max needed
365
* size, so that unwrap()s following a successful data transfer
366
* won't generate BUFFER_OVERFLOWS.
367
*
368
* We'll use a mix of direct and indirect ByteBuffers for
369
* tutorial purposes only. In reality, only use direct
370
* ByteBuffers when they give a clear performance enhancement.
371
*/
372
clientIn = ByteBuffer.allocate(appBufferMax + 50);
373
serverIn = ByteBuffer.allocate(appBufferMax + 50);
374
375
cTOs = ByteBuffer.allocateDirect(netBufferMax);
376
sTOc = ByteBuffer.allocateDirect(netBufferMax);
377
378
clientOut = ByteBuffer.wrap("Hi Server, I'm Client".getBytes());
379
serverOut = ByteBuffer.wrap("Hello Client, I'm Server".getBytes());
380
}
381
382
/*
383
* If the result indicates that we have outstanding tasks to do,
384
* go ahead and run them in this thread.
385
*/
386
private static void runDelegatedTasks(SSLEngine engine) throws Exception {
387
388
if (engine.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
389
Runnable runnable;
390
while ((runnable = engine.getDelegatedTask()) != null) {
391
log(" running delegated task...");
392
runnable.run();
393
}
394
HandshakeStatus hsStatus = engine.getHandshakeStatus();
395
if (hsStatus == HandshakeStatus.NEED_TASK) {
396
throw new Exception(
397
"handshake shouldn't need additional tasks");
398
}
399
logEngineStatus(engine);
400
}
401
}
402
403
private static boolean isEngineClosed(SSLEngine engine) {
404
return (engine.isOutboundDone() && engine.isInboundDone());
405
}
406
407
/*
408
* Simple check to make sure everything came across as expected.
409
*/
410
private static void checkTransfer(ByteBuffer a, ByteBuffer b)
411
throws Exception {
412
a.flip();
413
b.flip();
414
415
if (!a.equals(b)) {
416
throw new Exception("Data didn't transfer cleanly");
417
} else {
418
log("\tData transferred cleanly");
419
}
420
421
a.position(a.limit());
422
b.position(b.limit());
423
a.limit(a.capacity());
424
b.limit(b.capacity());
425
}
426
427
/*
428
* Logging code
429
*/
430
private static boolean resultOnce = true;
431
432
private static void log(String str, SSLEngineResult result) {
433
if (!logging) {
434
return;
435
}
436
if (resultOnce) {
437
resultOnce = false;
438
System.err.println("The format of the SSLEngineResult is: \n" +
439
"\t\"getStatus() / getHandshakeStatus()\" +\n" +
440
"\t\"bytesConsumed() / bytesProduced()\"\n");
441
}
442
HandshakeStatus hsStatus = result.getHandshakeStatus();
443
log(str +
444
result.getStatus() + "/" + hsStatus + ", " +
445
result.bytesConsumed() + "/" + result.bytesProduced() +
446
" bytes");
447
if (hsStatus == HandshakeStatus.FINISHED) {
448
log("\t...ready for application data");
449
}
450
}
451
452
private static void log(String str) {
453
if (logging) {
454
System.err.println(str);
455
}
456
}
457
}
458
459