Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/net/ssl/ALPN/SSLSocketAlpnTest.java
41152 views
1
/*
2
* Copyright (c) 2001, 2016, 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 8051498 8145849 8170282
30
* @summary JEP 244: TLS Application-Layer Protocol Negotiation Extension
31
* @compile MyX509ExtendedKeyManager.java
32
*
33
* @run main/othervm SSLSocketAlpnTest h2 UNUSED h2 h2
34
* @run main/othervm SSLSocketAlpnTest h2 UNUSED h2,http/1.1 h2
35
* @run main/othervm SSLSocketAlpnTest h2,http/1.1 UNUSED h2,http/1.1 h2
36
* @run main/othervm SSLSocketAlpnTest http/1.1,h2 UNUSED h2,http/1.1 http/1.1
37
* @run main/othervm SSLSocketAlpnTest h4,h3,h2 UNUSED h1,h2 h2
38
* @run main/othervm SSLSocketAlpnTest EMPTY UNUSED h2,http/1.1 NONE
39
* @run main/othervm SSLSocketAlpnTest h2 UNUSED EMPTY NONE
40
* @run main/othervm SSLSocketAlpnTest H2 UNUSED h2 ERROR
41
* @run main/othervm SSLSocketAlpnTest h2 UNUSED http/1.1 ERROR
42
*
43
* @run main/othervm SSLSocketAlpnTest UNUSED h2 h2 h2
44
* @run main/othervm SSLSocketAlpnTest UNUSED h2 h2,http/1.1 h2
45
* @run main/othervm SSLSocketAlpnTest UNUSED h2 http/1.1,h2 h2
46
* @run main/othervm SSLSocketAlpnTest UNUSED http/1.1 h2,http/1.1 http/1.1
47
* @run main/othervm SSLSocketAlpnTest UNUSED EMPTY h2,http/1.1 NONE
48
* @run main/othervm SSLSocketAlpnTest UNUSED h2 EMPTY NONE
49
* @run main/othervm SSLSocketAlpnTest UNUSED H2 h2 ERROR
50
* @run main/othervm SSLSocketAlpnTest UNUSED h2 http/1.1 ERROR
51
*
52
* @run main/othervm SSLSocketAlpnTest h2 h2 h2 h2
53
* @run main/othervm SSLSocketAlpnTest H2 h2 h2,http/1.1 h2
54
* @run main/othervm SSLSocketAlpnTest h2,http/1.1 http/1.1 h2,http/1.1 http/1.1
55
* @run main/othervm SSLSocketAlpnTest http/1.1,h2 h2 h2,http/1.1 h2
56
* @run main/othervm SSLSocketAlpnTest EMPTY h2 h2 h2
57
* @run main/othervm SSLSocketAlpnTest h2,http/1.1 EMPTY http/1.1 NONE
58
* @run main/othervm SSLSocketAlpnTest h2,http/1.1 h2 EMPTY NONE
59
* @run main/othervm SSLSocketAlpnTest UNUSED UNUSED http/1.1,h2 NONE
60
* @run main/othervm SSLSocketAlpnTest h2 h2 http/1.1 ERROR
61
* @run main/othervm SSLSocketAlpnTest h2,http/1.1 H2 http/1.1 ERROR
62
*
63
* @author Brad Wetmore
64
*/
65
/**
66
* A simple SSLSocket-based client/server that demonstrates the proposed API
67
* changes for JEP 244 in support of the TLS ALPN extension (RFC 7301).
68
*
69
* Usage:
70
* java SSLSocketAlpnTest <server-APs> <callback-AP> <client-APs> <result>
71
*
72
* where:
73
* EMPTY indicates that ALPN is disabled
74
* UNUSED indicates that no ALPN values are supplied (server-side only)
75
* ERROR indicates that an exception is expected
76
* NONE indicates that no ALPN is expected
77
*
78
* This example is based on our standard SSLSocketTemplate.
79
*/
80
import java.io.*;
81
import java.security.KeyStore;
82
import java.util.Arrays;
83
84
import javax.net.ssl.*;
85
86
public class SSLSocketAlpnTest {
87
88
/*
89
* =============================================================
90
* Set the various variables needed for the tests, then
91
* specify what tests to run on each side.
92
*/
93
94
/*
95
* Should we run the client or server in a separate thread?
96
* Both sides can throw exceptions, but do you have a preference
97
* as to which side should be the main thread.
98
*/
99
static boolean separateServerThread = false;
100
101
/*
102
* Where do we find the keystores?
103
*/
104
static String pathToStores = "../etc";
105
static String keyStoreFile = "keystore";
106
static String trustStoreFile = "truststore";
107
static String passwd = "passphrase";
108
109
static String keyFilename = System.getProperty("test.src", ".") + "/"
110
+ pathToStores + "/" + keyStoreFile;
111
static String trustFilename = System.getProperty("test.src", ".") + "/"
112
+ pathToStores + "/" + trustStoreFile;
113
114
private static boolean hasServerAPs; // whether server APs are present
115
private static boolean hasCallback; // whether a callback is present
116
117
/*
118
* SSLContext
119
*/
120
SSLContext mySSLContext = null;
121
122
/*
123
* Is the server ready to serve?
124
*/
125
volatile static boolean serverReady = false;
126
127
/*
128
* Turn on SSL debugging?
129
*/
130
static boolean debug = false;
131
132
static String[] serverAPs;
133
static String callbackAP;
134
static String[] clientAPs;
135
static String expectedAP;
136
137
/*
138
* If the client or server is doing some kind of object creation
139
* that the other side depends on, and that thread prematurely
140
* exits, you may experience a hang. The test harness will
141
* terminate all hung threads after its timeout has expired,
142
* currently 3 minutes by default, but you might try to be
143
* smart about it....
144
*/
145
146
/*
147
* Define the server side of the test.
148
*
149
* If the server prematurely exits, serverReady will be set to true
150
* to avoid infinite hangs.
151
*/
152
void doServerSide() throws Exception {
153
SSLServerSocketFactory sslssf = mySSLContext.getServerSocketFactory();
154
SSLServerSocket sslServerSocket
155
= (SSLServerSocket) sslssf.createServerSocket(serverPort);
156
// for both client/server to call into X509KM
157
sslServerSocket.setNeedClientAuth(true);
158
159
serverPort = sslServerSocket.getLocalPort();
160
161
/*
162
* Signal Client, we're ready for his connect.
163
*/
164
serverReady = true;
165
166
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
167
168
SSLParameters sslp = sslSocket.getSSLParameters();
169
170
/*
171
* The default ciphersuite ordering from the SSLContext may not
172
* reflect "h2" ciphersuites as being preferred, additionally the
173
* client may not send them in an appropriate order. We could resort
174
* the suite list if so desired.
175
*/
176
String[] suites = sslp.getCipherSuites();
177
sslp.setCipherSuites(suites);
178
sslp.setUseCipherSuitesOrder(true); // Set server side order
179
180
// Set the ALPN selection.
181
if (serverAPs != null) {
182
sslp.setApplicationProtocols(serverAPs);
183
}
184
sslSocket.setSSLParameters(sslp);
185
186
if (sslSocket.getHandshakeApplicationProtocol() != null) {
187
throw new Exception ("getHandshakeApplicationProtocol() should "
188
+ "return null before the handshake starts");
189
}
190
191
// check that no callback has been registered
192
if (sslSocket.getHandshakeApplicationProtocolSelector() != null) {
193
throw new Exception("getHandshakeApplicationProtocolSelector() " +
194
"should return null");
195
}
196
197
if (hasCallback) {
198
sslSocket.setHandshakeApplicationProtocolSelector(
199
(serverSocket, clientProtocols) -> {
200
return callbackAP.equals("EMPTY") ? "" : callbackAP;
201
});
202
203
// check that the callback can be retrieved
204
if (sslSocket.getHandshakeApplicationProtocolSelector() == null) {
205
throw new Exception("getHandshakeApplicationProtocolSelector()" + " should return non-null");
206
}
207
}
208
209
sslSocket.startHandshake();
210
211
if (sslSocket.getHandshakeApplicationProtocol() != null) {
212
throw new Exception ("getHandshakeApplicationProtocol() should "
213
+ "return null after the handshake is completed");
214
}
215
216
String ap = sslSocket.getApplicationProtocol();
217
System.out.println("Application Protocol: \"" + ap + "\"");
218
219
if (ap == null) {
220
throw new Exception(
221
"Handshake was completed but null was received");
222
}
223
if (expectedAP.equals("NONE")) {
224
if (!ap.isEmpty()) {
225
throw new Exception("Expected no ALPN value");
226
} else {
227
System.out.println("No ALPN value negotiated, as expected");
228
}
229
} else if (!expectedAP.equals(ap)) {
230
throw new Exception(expectedAP
231
+ " ALPN value not available on negotiated connection");
232
}
233
234
InputStream sslIS = sslSocket.getInputStream();
235
OutputStream sslOS = sslSocket.getOutputStream();
236
237
sslIS.read();
238
sslOS.write(85);
239
sslOS.flush();
240
241
sslSocket.close();
242
}
243
244
/*
245
* Define the client side of the test.
246
*
247
* If the server prematurely exits, serverReady will be set to true
248
* to avoid infinite hangs.
249
*/
250
void doClientSide() throws Exception {
251
252
/*
253
* Wait for server to get started.
254
*/
255
while (!serverReady) {
256
Thread.sleep(50);
257
}
258
259
SSLSocketFactory sslsf = mySSLContext.getSocketFactory();
260
SSLSocket sslSocket
261
= (SSLSocket) sslsf.createSocket("localhost", serverPort);
262
263
SSLParameters sslp = sslSocket.getSSLParameters();
264
265
/*
266
* The default ciphersuite ordering from the SSLContext may not
267
* reflect "h2" ciphersuites as being preferred, additionally the
268
* client may not send them in an appropriate order. We could resort
269
* the suite list if so desired.
270
*/
271
String[] suites = sslp.getCipherSuites();
272
sslp.setCipherSuites(suites);
273
sslp.setUseCipherSuitesOrder(true); // Set server side order
274
275
// Set the ALPN selection.
276
sslp.setApplicationProtocols(clientAPs);
277
sslSocket.setSSLParameters(sslp);
278
279
if (sslSocket.getHandshakeApplicationProtocol() != null) {
280
throw new Exception ("getHandshakeApplicationProtocol() should "
281
+ "return null before the handshake starts");
282
}
283
284
sslSocket.startHandshake();
285
286
if (sslSocket.getHandshakeApplicationProtocol() != null) {
287
throw new Exception ("getHandshakeApplicationProtocol() should "
288
+ "return null after the handshake is completed");
289
}
290
291
/*
292
* Check that the resulting connection meets our defined ALPN
293
* criteria. If we were connecting to a non-JSSE implementation,
294
* the server might have negotiated something we shouldn't accept.
295
*/
296
String ap = sslSocket.getApplicationProtocol();
297
System.out.println("Application Protocol: \"" + ap + "\"");
298
299
if (ap == null) {
300
throw new Exception(
301
"Handshake was completed but null was received");
302
}
303
if (expectedAP.equals("NONE")) {
304
if (!ap.isEmpty()) {
305
throw new Exception("Expected no ALPN value");
306
} else {
307
System.out.println("No ALPN value negotiated, as expected");
308
}
309
} else if (!expectedAP.equals(ap)) {
310
throw new Exception(expectedAP
311
+ " ALPN value not available on negotiated connection");
312
}
313
314
InputStream sslIS = sslSocket.getInputStream();
315
OutputStream sslOS = sslSocket.getOutputStream();
316
317
sslOS.write(280);
318
sslOS.flush();
319
sslIS.read();
320
321
sslSocket.close();
322
}
323
324
/*
325
* =============================================================
326
* The remainder is just support stuff
327
*/
328
// use any free port by default
329
volatile int serverPort = 0;
330
331
volatile Exception serverException = null;
332
volatile Exception clientException = null;
333
334
public static void main(String[] args) throws Exception {
335
336
if (debug) {
337
System.setProperty("javax.net.debug", "all");
338
}
339
System.out.println("Test args: " + Arrays.toString(args));
340
341
// Validate parameters
342
if (args.length != 4) {
343
throw new Exception("Invalid number of test parameters");
344
}
345
serverAPs = convert(args[0]);
346
callbackAP = args[1];
347
clientAPs = convert(args[2]);
348
expectedAP = args[3];
349
350
hasServerAPs = !args[0].equals("UNUSED"); // are server APs being used?
351
hasCallback = !callbackAP.equals("UNUSED"); // is callback being used?
352
353
/*
354
* Start the tests.
355
*/
356
try {
357
new SSLSocketAlpnTest();
358
} catch (SSLHandshakeException she) {
359
if (args[3].equals("ERROR")) {
360
System.out.println("Caught the expected exception: " + she);
361
} else {
362
throw she;
363
}
364
}
365
366
System.out.println("Test Passed.");
367
}
368
369
SSLContext getSSLContext(String keyFilename, String trustFilename)
370
throws Exception {
371
SSLContext ctx = SSLContext.getInstance("TLS");
372
373
// Keystores
374
KeyStore keyKS = KeyStore.getInstance("JKS");
375
keyKS.load(new FileInputStream(keyFilename), passwd.toCharArray());
376
377
KeyStore trustKS = KeyStore.getInstance("JKS");
378
trustKS.load(new FileInputStream(trustFilename), passwd.toCharArray());
379
380
// Generate KeyManager and TrustManager
381
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
382
kmf.init(keyKS, passwd.toCharArray());
383
384
KeyManager[] kms = kmf.getKeyManagers();
385
if (!(kms[0] instanceof X509ExtendedKeyManager)) {
386
throw new Exception("kms[0] not X509ExtendedKeyManager");
387
}
388
389
kms = new KeyManager[] { new MyX509ExtendedKeyManager(
390
(X509ExtendedKeyManager) kms[0], expectedAP,
391
!hasCallback && hasServerAPs) };
392
393
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
394
tmf.init(trustKS);
395
TrustManager[] tms = tmf.getTrustManagers();
396
397
// initial SSLContext
398
ctx.init(kms, tms, null);
399
400
return ctx;
401
}
402
403
/*
404
* Convert a comma-separated list into an array of strings.
405
*/
406
private static String[] convert(String list) {
407
if (list.equals("UNUSED")) {
408
return null;
409
}
410
411
if (list.equals("EMPTY")) {
412
return new String[0];
413
}
414
415
String[] strings;
416
if (list.indexOf(',') > 0) {
417
strings = list.split(",");
418
} else {
419
strings = new String[]{ list };
420
}
421
422
return strings;
423
}
424
425
Thread clientThread = null;
426
Thread serverThread = null;
427
428
/*
429
* Primary constructor, used to drive remainder of the test.
430
*
431
* Fork off the other side, then do your work.
432
*/
433
SSLSocketAlpnTest() throws Exception {
434
Exception startException = null;
435
mySSLContext = getSSLContext(keyFilename, trustFilename);
436
try {
437
if (separateServerThread) {
438
startServer(true);
439
startClient(false);
440
} else {
441
startClient(true);
442
startServer(false);
443
}
444
} catch (Exception e) {
445
startException = e;
446
}
447
448
/*
449
* Wait for other side to close down.
450
*/
451
if (separateServerThread) {
452
if (serverThread != null) {
453
serverThread.join();
454
}
455
} else {
456
if (clientThread != null) {
457
clientThread.join();
458
}
459
}
460
461
/*
462
* When we get here, the test is pretty much over.
463
* Which side threw the error?
464
*/
465
Exception local;
466
Exception remote;
467
468
if (separateServerThread) {
469
remote = serverException;
470
local = clientException;
471
} else {
472
remote = clientException;
473
local = serverException;
474
}
475
476
Exception exception = null;
477
478
/*
479
* Check various exception conditions.
480
*/
481
if ((local != null) && (remote != null)) {
482
// If both failed, return the curthread's exception.
483
local.initCause(remote);
484
exception = local;
485
} else if (local != null) {
486
exception = local;
487
} else if (remote != null) {
488
exception = remote;
489
} else if (startException != null) {
490
exception = startException;
491
}
492
493
/*
494
* If there was an exception *AND* a startException,
495
* output it.
496
*/
497
if (exception != null) {
498
if (exception != startException && startException != null) {
499
exception.addSuppressed(startException);
500
}
501
throw exception;
502
}
503
504
// Fall-through: no exception to throw!
505
}
506
507
void startServer(boolean newThread) throws Exception {
508
if (newThread) {
509
serverThread = new Thread() {
510
@Override
511
public void run() {
512
try {
513
doServerSide();
514
} catch (Exception e) {
515
/*
516
* Our server thread just died.
517
*
518
* Release the client, if not active already...
519
*/
520
System.err.println("Server died...");
521
serverReady = true;
522
serverException = e;
523
}
524
}
525
};
526
serverThread.start();
527
} else {
528
try {
529
doServerSide();
530
} catch (Exception e) {
531
serverException = e;
532
} finally {
533
serverReady = true;
534
}
535
}
536
}
537
538
void startClient(boolean newThread) throws Exception {
539
if (newThread) {
540
clientThread = new Thread() {
541
@Override
542
public void run() {
543
try {
544
doClientSide();
545
} catch (Exception e) {
546
/*
547
* Our client thread just died.
548
*/
549
System.err.println("Client died...");
550
clientException = e;
551
}
552
}
553
};
554
clientThread.start();
555
} else {
556
try {
557
doClientSide();
558
} catch (Exception e) {
559
clientException = e;
560
}
561
}
562
}
563
}
564
565