Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/net/ssl/sanity/interop/CipherTest.java
41154 views
1
/*
2
* Copyright (c) 2002, 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
import java.io.*;
25
import java.net.*;
26
import java.util.*;
27
import java.util.concurrent.*;
28
29
import java.security.*;
30
import java.security.cert.*;
31
32
import javax.net.ssl.*;
33
34
/**
35
* Test that all ciphersuites work in all versions and all client
36
* authentication types. The way this is setup the server is stateless and
37
* all checking is done on the client side.
38
*
39
* The test is multithreaded to speed it up, especially on multiprocessor
40
* machines. To simplify debugging, run with -DnumThreads=1.
41
*
42
* @author Andreas Sterbenz
43
*/
44
public class CipherTest {
45
46
// use any available port for the server socket
47
static int serverPort = 0;
48
49
final int THREADS;
50
51
// assume that if we do not read anything for 20 seconds, something
52
// has gone wrong
53
final static int TIMEOUT = 20 * 1000;
54
55
static KeyStore trustStore, keyStore;
56
static X509ExtendedKeyManager keyManager;
57
static X509TrustManager trustManager;
58
static SecureRandom secureRandom;
59
60
private static PeerFactory peerFactory;
61
62
static abstract class Server implements Runnable {
63
64
final CipherTest cipherTest;
65
66
Server(CipherTest cipherTest) throws Exception {
67
this.cipherTest = cipherTest;
68
}
69
70
public abstract void run();
71
72
void handleRequest(InputStream in, OutputStream out) throws IOException {
73
boolean newline = false;
74
StringBuilder sb = new StringBuilder();
75
while (true) {
76
int ch = in.read();
77
if (ch < 0) {
78
throw new EOFException();
79
}
80
sb.append((char)ch);
81
if (ch == '\r') {
82
// empty
83
} else if (ch == '\n') {
84
if (newline) {
85
// 2nd newline in a row, end of request
86
break;
87
}
88
newline = true;
89
} else {
90
newline = false;
91
}
92
}
93
String request = sb.toString();
94
if (request.startsWith("GET / HTTP/1.") == false) {
95
throw new IOException("Invalid request: " + request);
96
}
97
out.write("HTTP/1.0 200 OK\r\n\r\n".getBytes());
98
}
99
100
}
101
102
public static class TestParameters {
103
104
CipherSuite cipherSuite;
105
Protocol protocol;
106
String clientAuth;
107
108
TestParameters(CipherSuite cipherSuite, Protocol protocol,
109
String clientAuth) {
110
this.cipherSuite = cipherSuite;
111
this.protocol = protocol;
112
this.clientAuth = clientAuth;
113
}
114
115
boolean isEnabled() {
116
return cipherSuite.supportedByProtocol(protocol);
117
}
118
119
public String toString() {
120
String s = cipherSuite + " in " + protocol + " mode";
121
if (clientAuth != null) {
122
s += " with " + clientAuth + " client authentication";
123
}
124
return s;
125
}
126
}
127
128
private List<TestParameters> tests;
129
private Iterator<TestParameters> testIterator;
130
private SSLSocketFactory factory;
131
private boolean failed;
132
133
private CipherTest(PeerFactory peerFactory) throws IOException {
134
THREADS = Integer.parseInt(System.getProperty("numThreads", "4"));
135
factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
136
SSLSocket socket = (SSLSocket)factory.createSocket();
137
String[] cipherSuites = socket.getSupportedCipherSuites();
138
String[] protocols = socket.getSupportedProtocols();
139
String[] clientAuths = {null, "RSA", "DSA"};
140
tests = new ArrayList<TestParameters>(
141
cipherSuites.length * protocols.length * clientAuths.length);
142
for (int j = 0; j < protocols.length; j++) {
143
String protocol = protocols[j];
144
if (protocol.equals(Protocol.SSLV2HELLO.name)) {
145
System.out.println("Skipping SSLv2Hello protocol");
146
continue;
147
}
148
149
for (int i = 0; i < cipherSuites.length; i++) {
150
String cipherSuite = cipherSuites[i];
151
152
// skip kerberos cipher suites and TLS_EMPTY_RENEGOTIATION_INFO_SCSV
153
if (cipherSuite.startsWith("TLS_KRB5") || cipherSuite.equals(
154
CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV.name())) {
155
System.out.println("Skipping unsupported test for " +
156
cipherSuite + " of " + protocol);
157
continue;
158
}
159
160
if (!peerFactory.isSupported(cipherSuite, protocol)) {
161
continue;
162
}
163
164
for (int k = 0; k < clientAuths.length; k++) {
165
String clientAuth = clientAuths[k];
166
// no client with anonymous cipher suites;
167
// TLS 1.3 doesn't support DSA
168
if ((clientAuth != null && cipherSuite.contains("DH_anon"))
169
|| ("DSA".equals(clientAuth) && "TLSv1.3".equals(protocol))) {
170
continue;
171
}
172
tests.add(new TestParameters(
173
CipherSuite.cipherSuite(cipherSuite),
174
Protocol.protocol(protocol),
175
clientAuth));
176
}
177
}
178
}
179
testIterator = tests.iterator();
180
}
181
182
synchronized void setFailed() {
183
failed = true;
184
}
185
186
public void run() throws Exception {
187
Thread[] threads = new Thread[THREADS];
188
for (int i = 0; i < THREADS; i++) {
189
try {
190
threads[i] = new Thread(peerFactory.newClient(this),
191
"Client " + i);
192
} catch (Exception e) {
193
e.printStackTrace();
194
return;
195
}
196
threads[i].start();
197
}
198
try {
199
for (int i = 0; i < THREADS; i++) {
200
threads[i].join();
201
}
202
} catch (InterruptedException e) {
203
setFailed();
204
e.printStackTrace();
205
}
206
if (failed) {
207
throw new Exception("*** Test '" + peerFactory.getName() +
208
"' failed ***");
209
} else {
210
System.out.println("Test '" + peerFactory.getName() +
211
"' completed successfully");
212
}
213
}
214
215
synchronized TestParameters getTest() {
216
if (failed) {
217
return null;
218
}
219
if (testIterator.hasNext()) {
220
return (TestParameters)testIterator.next();
221
}
222
return null;
223
}
224
225
SSLSocketFactory getFactory() {
226
return factory;
227
}
228
229
static abstract class Client implements Runnable {
230
231
final CipherTest cipherTest;
232
233
Client(CipherTest cipherTest) throws Exception {
234
this.cipherTest = cipherTest;
235
}
236
237
public final void run() {
238
while (true) {
239
TestParameters params = cipherTest.getTest();
240
if (params == null) {
241
// no more tests
242
break;
243
}
244
if (!params.isEnabled()) {
245
System.out.println("Skipping disabled test " + params);
246
continue;
247
}
248
try {
249
runTest(params);
250
System.out.println("Passed " + params);
251
} catch (Exception e) {
252
cipherTest.setFailed();
253
System.out.println("** Failed " + params + "**");
254
e.printStackTrace();
255
}
256
}
257
}
258
259
abstract void runTest(TestParameters params) throws Exception;
260
261
void sendRequest(InputStream in, OutputStream out) throws IOException {
262
out.write("GET / HTTP/1.0\r\n\r\n".getBytes());
263
out.flush();
264
StringBuilder sb = new StringBuilder();
265
while (true) {
266
int ch = in.read();
267
if (ch < 0) {
268
break;
269
}
270
sb.append((char)ch);
271
}
272
String response = sb.toString();
273
if (response.startsWith("HTTP/1.0 200 ") == false) {
274
throw new IOException("Invalid response: " + response);
275
}
276
}
277
278
}
279
280
// for some reason, ${test.src} has a different value when the
281
// test is called from the script and when it is called directly...
282
static String pathToStores = "../../etc";
283
static String pathToStoresSH = ".";
284
static String keyStoreFile = "keystore";
285
static String trustStoreFile = "truststore";
286
static char[] passwd = "passphrase".toCharArray();
287
288
static File PATH;
289
290
private static KeyStore readKeyStore(String name) throws Exception {
291
File file = new File(PATH, name);
292
InputStream in = new FileInputStream(file);
293
KeyStore ks = KeyStore.getInstance("JKS");
294
ks.load(in, passwd);
295
in.close();
296
return ks;
297
}
298
299
public static void main(PeerFactory peerFactory, String[] args)
300
throws Exception {
301
long time = System.currentTimeMillis();
302
String relPath;
303
if ((args != null) && (args.length > 0) && args[0].equals("sh")) {
304
relPath = pathToStoresSH;
305
} else {
306
relPath = pathToStores;
307
}
308
PATH = new File(System.getProperty("test.src", "."), relPath);
309
CipherTest.peerFactory = peerFactory;
310
System.out.println(
311
"Initializing test '" + peerFactory.getName() + "'...");
312
secureRandom = new SecureRandom();
313
secureRandom.nextInt();
314
trustStore = readKeyStore(trustStoreFile);
315
keyStore = readKeyStore(keyStoreFile);
316
KeyManagerFactory keyFactory =
317
KeyManagerFactory.getInstance(
318
KeyManagerFactory.getDefaultAlgorithm());
319
keyFactory.init(keyStore, passwd);
320
keyManager = (X509ExtendedKeyManager)keyFactory.getKeyManagers()[0];
321
trustManager = new AlwaysTrustManager();
322
323
CipherTest cipherTest = new CipherTest(peerFactory);
324
Thread serverThread = new Thread(peerFactory.newServer(cipherTest),
325
"Server");
326
serverThread.setDaemon(true);
327
serverThread.start();
328
System.out.println("Done");
329
cipherTest.run();
330
time = System.currentTimeMillis() - time;
331
System.out.println("Done. (" + time + " ms)");
332
}
333
334
static abstract class PeerFactory {
335
336
abstract String getName();
337
338
abstract Client newClient(CipherTest cipherTest) throws Exception;
339
340
abstract Server newServer(CipherTest cipherTest) throws Exception;
341
342
boolean isSupported(String cipherSuite, String protocol) {
343
// ignore exportable cipher suite for TLSv1.1
344
if (protocol.equals("TLSv1.1")
345
&& (cipherSuite.indexOf("_EXPORT_WITH") != -1)) {
346
System.out.println("Skipping obsoleted test for " +
347
cipherSuite + " of " + protocol);
348
return false;
349
}
350
351
// ignore obsoleted cipher suite for the specified protocol
352
// TODO
353
354
// ignore unsupported cipher suite for the specified protocol
355
// TODO
356
357
return true;
358
}
359
}
360
361
}
362
363
// we currently don't do any chain verification. we assume that works ok
364
// and we can speed up the test. we could also just add a plain certificate
365
// chain comparision with our trusted certificates.
366
class AlwaysTrustManager implements X509TrustManager {
367
368
public AlwaysTrustManager() {
369
370
}
371
372
public void checkClientTrusted(X509Certificate[] chain, String authType)
373
throws CertificateException {
374
// empty
375
}
376
377
public void checkServerTrusted(X509Certificate[] chain, String authType)
378
throws CertificateException {
379
// empty
380
}
381
382
public X509Certificate[] getAcceptedIssuers() {
383
return new X509Certificate[0];
384
}
385
}
386
387
class MyX509KeyManager extends X509ExtendedKeyManager {
388
389
private final X509ExtendedKeyManager keyManager;
390
private String authType;
391
392
MyX509KeyManager(X509ExtendedKeyManager keyManager) {
393
this.keyManager = keyManager;
394
}
395
396
void setAuthType(String authType) {
397
this.authType = authType;
398
}
399
400
public String[] getClientAliases(String keyType, Principal[] issuers) {
401
if (authType == null) {
402
return null;
403
}
404
return keyManager.getClientAliases(authType, issuers);
405
}
406
407
public String chooseClientAlias(String[] keyType, Principal[] issuers,
408
Socket socket) {
409
if (authType == null) {
410
return null;
411
}
412
return keyManager.chooseClientAlias(new String[] {authType},
413
issuers, socket);
414
}
415
416
public String chooseEngineClientAlias(String[] keyType,
417
Principal[] issuers, SSLEngine engine) {
418
if (authType == null) {
419
return null;
420
}
421
return keyManager.chooseEngineClientAlias(new String[] {authType},
422
issuers, engine);
423
}
424
425
public String[] getServerAliases(String keyType, Principal[] issuers) {
426
throw new UnsupportedOperationException("Servers not supported");
427
}
428
429
public String chooseServerAlias(String keyType, Principal[] issuers,
430
Socket socket) {
431
throw new UnsupportedOperationException("Servers not supported");
432
}
433
434
public String chooseEngineServerAlias(String keyType, Principal[] issuers,
435
SSLEngine engine) {
436
throw new UnsupportedOperationException("Servers not supported");
437
}
438
439
public X509Certificate[] getCertificateChain(String alias) {
440
return keyManager.getCertificateChain(alias);
441
}
442
443
public PrivateKey getPrivateKey(String alias) {
444
return keyManager.getPrivateKey(alias);
445
}
446
447
}
448
449
class DaemonThreadFactory implements ThreadFactory {
450
451
final static ThreadFactory INSTANCE = new DaemonThreadFactory();
452
453
private final static ThreadFactory DEFAULT = Executors.defaultThreadFactory();
454
455
public Thread newThread(Runnable r) {
456
Thread t = DEFAULT.newThread(r);
457
t.setDaemon(true);
458
return t;
459
}
460
461
}
462
463