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