Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/net/ssl/TLSCommon/interop/Utilities.java
41154 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
import java.io.ByteArrayInputStream;
25
import java.io.File;
26
import java.io.IOException;
27
import java.io.InputStream;
28
import java.io.OutputStream;
29
import java.lang.reflect.Array;
30
import java.nio.charset.Charset;
31
import java.nio.charset.StandardCharsets;
32
import java.nio.file.Files;
33
import java.nio.file.Path;
34
import java.security.KeyFactory;
35
import java.security.KeyStore;
36
import java.security.KeyStoreException;
37
import java.security.NoSuchAlgorithmException;
38
import java.security.PrivateKey;
39
import java.security.cert.Certificate;
40
import java.security.cert.CertificateException;
41
import java.security.cert.CertificateFactory;
42
import java.security.spec.InvalidKeySpecException;
43
import java.security.spec.PKCS8EncodedKeySpec;
44
import java.util.Arrays;
45
import java.util.Base64;
46
import java.util.Optional;
47
import java.util.StringJoiner;
48
import java.util.concurrent.TimeUnit;
49
import java.util.function.Function;
50
import java.util.function.Predicate;
51
import java.util.stream.Collectors;
52
53
import javax.net.ssl.KeyManagerFactory;
54
import javax.net.ssl.SSLContext;
55
import javax.net.ssl.TrustManagerFactory;
56
57
import jdk.test.lib.process.OutputAnalyzer;
58
59
/*
60
* Utilities for interop testing.
61
*/
62
public class Utilities {
63
64
public static final String JAVA_HOME = System.getProperty("java.home");
65
public static final String JAVA
66
= String.join(File.separator, JAVA_HOME, "bin", "java");
67
public static final String JAVAC
68
= String.join(File.separator, JAVA_HOME, "bin", "javac");
69
70
public static final String TEST_SRC = System.getProperty("test.src");
71
public static final String TEST_CLASSES = System.getProperty("test.classes");
72
public static final String TEST_CLASSPATH = System.getProperty("test.class.path");
73
74
public static final Charset CHARSET = StandardCharsets.UTF_8;
75
76
public static final boolean DEBUG = Boolean.getBoolean("test.debug");
77
public static final int TIMEOUT = Integer.getInteger("test.timeout", 20);
78
public static final String LOG_PATH = System.getProperty("test.log.path");
79
80
public static final String PARAM_DELIMITER = ";";
81
public static final String VALUE_DELIMITER = ",";
82
83
public static final CipherSuite[] ALL_CIPHER_SUITES = getAllCipherSuites();
84
85
/*
86
* Gets all supported cipher suites.
87
*/
88
private static CipherSuite[] getAllCipherSuites() {
89
String[] supportedCipherSuites;
90
try {
91
supportedCipherSuites = SSLContext.getDefault()
92
.createSSLEngine()
93
.getSupportedCipherSuites();
94
} catch (NoSuchAlgorithmException e) {
95
throw new RuntimeException(
96
"Failed to get supported cipher suites", e);
97
}
98
99
CipherSuite[] cipherSuites = Arrays.stream(supportedCipherSuites)
100
.map(cipherSuite -> {
101
return CipherSuite.cipherSuite(cipherSuite);})
102
.filter(cipherSuite -> {
103
return cipherSuite != CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV; })
104
.toArray(CipherSuite[]::new);
105
106
return cipherSuites;
107
}
108
109
/*
110
* Creates SSL context with the specified certificates.
111
*/
112
public static SSLContext createSSLContext(CertTuple certTuple)
113
throws Exception {
114
KeyStore trustStore = createTrustStore(certTuple.trustedCerts);
115
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
116
tmf.init(trustStore);
117
118
KeyStore keyStore = createKeyStore(certTuple.endEntityCerts);
119
KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
120
kmf.init(keyStore, null);
121
122
SSLContext context = SSLContext.getInstance("TLS");
123
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
124
return context;
125
}
126
127
/*
128
* Creates trust store with the specified certificates.
129
*/
130
public static KeyStore createTrustStore(Cert... certs)
131
throws KeyStoreException, IOException, NoSuchAlgorithmException,
132
CertificateException {
133
KeyStore trustStore = KeyStore.getInstance("PKCS12");
134
trustStore.load(null, null);
135
136
if (certs != null) {
137
for (int i = 0; i < certs.length; i++) {
138
if (certs[i] != null) {
139
trustStore.setCertificateEntry("trust-" + i,
140
createCert(certs[i]));
141
}
142
}
143
}
144
145
return trustStore;
146
}
147
148
/*
149
* Creates key store with the specified certificates.
150
*/
151
public static KeyStore createKeyStore(Cert... certs)
152
throws KeyStoreException, IOException, NoSuchAlgorithmException,
153
CertificateException, InvalidKeySpecException {
154
KeyStore keyStore = KeyStore.getInstance("PKCS12");
155
keyStore.load(null, null);
156
157
if (certs != null) {
158
for (int i = 0; i < certs.length; i++) {
159
if (certs[i] != null) {
160
keyStore.setKeyEntry("cert-" + i, createKey(certs[i]), null,
161
new Certificate[] { createCert(certs[i]) });
162
}
163
}
164
}
165
166
return keyStore;
167
}
168
169
/*
170
* Creates Certificate instance with the specified certificate.
171
*/
172
public static Certificate createCert(Cert cert) {
173
try {
174
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
175
return certFactory.generateCertificate(
176
new ByteArrayInputStream(cert.certMaterials.getBytes()));
177
} catch (CertificateException e) {
178
throw new RuntimeException("Create cert failed: " + cert, e);
179
}
180
}
181
182
/*
183
* Creates PrivateKey instance with the specified certificate.
184
*/
185
public static PrivateKey createKey(Cert cert)
186
throws NoSuchAlgorithmException, InvalidKeySpecException {
187
PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(
188
Base64.getMimeDecoder().decode(cert.keyMaterials));
189
KeyFactory keyFactory = KeyFactory.getInstance(
190
cert.keyAlgo.name);
191
PrivateKey privKey = keyFactory.generatePrivate(privKeySpec);
192
return privKey;
193
}
194
195
/*
196
* Reads an input stream, in which the content length isn't more than 1024.
197
*/
198
public static String readIn(InputStream input) throws IOException {
199
byte[] buf = new byte[1024];
200
int length = input.read(buf);
201
if (length > 0) {
202
return new String(buf, 0, length);
203
} else {
204
return "";
205
}
206
}
207
208
/*
209
* Writes the specified content to an output stream.
210
*/
211
public static void writeOut(OutputStream output, String content)
212
throws IOException {
213
output.write(content.getBytes(Utilities.CHARSET));
214
output.flush();
215
}
216
217
/*
218
* Sleeps until the condition is true or getting timeout.
219
*/
220
public static <T> boolean waitFor(Predicate<T> predicate, T t) {
221
long deadline = System.currentTimeMillis() + Utilities.TIMEOUT * 1000;
222
boolean predicateResult = predicate.test(t);
223
while (!predicateResult && System.currentTimeMillis() < deadline) {
224
try {
225
TimeUnit.SECONDS.sleep(1);
226
predicateResult = predicate.test(t);
227
} catch (InterruptedException e) {
228
throw new RuntimeException("Sleep is interrupted.", e);
229
}
230
}
231
232
return predicateResult;
233
}
234
235
/*
236
* Converts Enum array to string array.
237
* The string elements are the Enum names.
238
*/
239
public static String[] enumsToStrs(Enum<?>... elements) {
240
return enumsToStrs(element -> {
241
return element.name();
242
}, elements);
243
}
244
245
/*
246
* Converts NamedGroup array to string array.
247
* The string elements are the NameGroups' names.
248
*/
249
public static String[] namedGroupsToStrs(NamedGroup... namedGroups) {
250
return enumsToStrs(namedGroup -> {
251
return ((NamedGroup) namedGroup).name;
252
}, namedGroups);
253
}
254
255
/*
256
* Converts Enum array to string array.
257
* The string elements are determined by the specified Function.
258
*/
259
public static String[] enumsToStrs(Function<Enum<?>, String> function,
260
Enum<?>... elements) {
261
return elements == null
262
? null
263
: Arrays.stream(elements).map(function).toArray(String[]::new);
264
}
265
266
/*
267
* Converts string array to Enum array.
268
*/
269
@SuppressWarnings("unchecked")
270
public static <T extends Enum<T>> T[] strToEnums(Class<T> enumType,
271
String namesStr) {
272
if (namesStr == null) {
273
return null;
274
}
275
276
return Arrays.stream(namesStr.split(VALUE_DELIMITER)).map(name -> {
277
return Enum.valueOf(enumType, name);
278
}).collect(Collectors.toList()).toArray(
279
(T[]) Array.newInstance(enumType, 0));
280
}
281
282
/*
283
* Determines if the specified process is alive.
284
*/
285
public static boolean isAliveProcess(Process process) {
286
return process != null && process.isAlive();
287
}
288
289
/*
290
* Destroys the specified process and the associated child processes.
291
*/
292
public static void destroyProcess(Process process) {
293
process.children().forEach(ProcessHandle::destroy);
294
process.destroy();
295
}
296
297
/*
298
* Reads the content for the specified file.
299
*/
300
public static Optional<String> readFile(Path path) throws IOException {
301
if (!Files.exists(path)) {
302
return Optional.empty();
303
} else {
304
return Optional.of(new String(Files.readAllBytes(path)));
305
}
306
}
307
308
/*
309
* Tries to delete the specified file before getting timeout,
310
* in case that the file is not released by some process in time.
311
*/
312
public static void deleteFile(Path filePath) throws IOException {
313
if (filePath == null) {
314
return;
315
}
316
317
waitFor(path -> delete(path), filePath);
318
if (Files.exists(filePath)) {
319
throw new IOException(
320
"File is not deleted in time: " + filePath.toAbsolutePath());
321
}
322
}
323
324
private static boolean delete(Path filePath) {
325
boolean deleted = false;
326
try {
327
deleted = Files.deleteIfExists(filePath);
328
} catch (IOException e) {
329
e.printStackTrace(System.out);
330
}
331
332
return deleted;
333
}
334
335
/*
336
* Determines if the TLS session is resumed.
337
*/
338
public static boolean isSessionResumed(ResumptionMode mode,
339
byte[] firstSessionId, byte[] secondSessionId,
340
long firstSessionCreationTime, long secondSessionCreationTime) {
341
System.out.println("ResumptionMode: " + mode);
342
System.out.println("firstSessionId: " + Arrays.toString(firstSessionId));
343
System.out.println("secondSessionId: " + Arrays.toString(secondSessionId));
344
System.out.println("firstSessionCreationTime: " + firstSessionCreationTime);
345
System.out.println("secondSessionCreationTime: " + secondSessionCreationTime);
346
347
boolean resumed = firstSessionCreationTime == secondSessionCreationTime;
348
if (mode == ResumptionMode.ID) {
349
resumed = resumed && firstSessionId.length > 0
350
&& Arrays.equals(firstSessionId, secondSessionId);
351
}
352
return resumed;
353
}
354
355
@SuppressWarnings("unchecked")
356
public static <T> String join(String delimiter, Function<T, String> toStr,
357
T... elements) {
358
if (elements == null) {
359
return "";
360
}
361
362
StringJoiner joiner = new StringJoiner(delimiter);
363
for (T element : elements) {
364
if (element != null) {
365
String str = toStr.apply(element);
366
if (str != null && !str.isEmpty()) {
367
joiner.add(str);
368
}
369
}
370
}
371
return joiner.toString();
372
}
373
374
@SuppressWarnings("unchecked")
375
public static <T> String join(String delimiter, T... elements) {
376
return join(delimiter, elem -> {
377
return elem.toString();
378
}, elements);
379
}
380
381
@SuppressWarnings("unchecked")
382
public static <T> String join(T... elements) {
383
return join(VALUE_DELIMITER, elements);
384
}
385
386
@SuppressWarnings("unchecked")
387
public static <T> String join(Function<T, String> toStr, T... elements) {
388
return join(VALUE_DELIMITER, toStr, elements);
389
}
390
391
public static String joinOptValue(String delimiter, String option,
392
Object value) {
393
return value == null || value.toString().isEmpty()
394
? ""
395
: option + delimiter + value;
396
}
397
398
public static String joinOptValue(String option, Object value) {
399
return joinOptValue(" ", option, value);
400
}
401
402
public static String joinNameValue(String option, Object value) {
403
return joinOptValue("=", option, value);
404
}
405
406
public static String[] split(String str, String delimiter) {
407
if (str == null) {
408
return null;
409
}
410
411
return str.split(delimiter);
412
}
413
414
public static String[] split(String str) {
415
return split(str, VALUE_DELIMITER);
416
}
417
418
public static String trimStr(String str) {
419
return str == null ? "" : str.trim();
420
}
421
422
public static boolean isEmpty(String str) {
423
return str == null || str.isEmpty();
424
}
425
426
/*
427
* Determines the expected negotiated application protocol from the server
428
* and client application protocols.
429
*/
430
public static String expectedNegoAppProtocol(String[] serverAppProtocols,
431
String[] clientAppProtocols) {
432
if (serverAppProtocols != null && clientAppProtocols != null) {
433
for(String clientAppProtocol : clientAppProtocols) {
434
for(String serverAppProtocol : serverAppProtocols) {
435
if (clientAppProtocol.equals(serverAppProtocol)) {
436
return clientAppProtocol;
437
}
438
}
439
}
440
}
441
442
return null;
443
}
444
445
/*
446
* Finds the minimum protocol in the specified protocols.
447
*/
448
public static Protocol minProtocol(Protocol[] protocols) {
449
return findProtocol(protocols, true);
450
}
451
452
/*
453
* Finds the maximum protocol in the specified protocols.
454
*/
455
public static Protocol maxProtocol(Protocol[] protocols) {
456
return findProtocol(protocols, false);
457
}
458
459
private static Protocol findProtocol(Protocol[] protocols, boolean findMin) {
460
if (protocols == null) {
461
return null;
462
}
463
464
Arrays.sort(protocols, (p1, p2) -> {
465
return (p1.id - p2.id) * (findMin ? 1 : -1);
466
});
467
return protocols[0];
468
}
469
}
470
471