Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.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
/*
25
* SunJSSE does not support dynamic system properties, no way to re-use
26
* system properties in samevm/agentvm mode.
27
* For extra debugging output, add -Djavax.net.debug=ssl:handshake into the
28
* run directive below.
29
*/
30
31
/*
32
* @test
33
* @bug 8166596
34
* @summary TLS support for the EdDSA signature algorithm
35
* @library /javax/net/ssl/templates /test/lib
36
* @run main/othervm TLSWithEdDSA
37
*/
38
39
import java.io.ByteArrayInputStream;
40
import java.io.IOException;
41
import java.io.InputStream;
42
import java.io.OutputStream;
43
import java.net.Socket;
44
import java.net.SocketException;
45
import java.nio.charset.Charset;
46
import java.security.GeneralSecurityException;
47
import java.security.KeyFactory;
48
import java.security.KeyStore;
49
import java.security.KeyStoreException;
50
import java.security.Principal;
51
import java.security.PrivateKey;
52
import java.security.PublicKey;
53
import java.security.cert.Certificate;
54
import java.security.cert.CertificateException;
55
import java.security.cert.CertificateFactory;
56
import java.security.cert.PKIXBuilderParameters;
57
import java.security.cert.X509CertSelector;
58
import java.security.cert.X509Certificate;
59
import java.security.interfaces.ECKey;
60
import java.security.interfaces.EdECKey;
61
import java.security.spec.PKCS8EncodedKeySpec;
62
import java.util.*;
63
import javax.net.ssl.CertPathTrustManagerParameters;
64
import javax.net.ssl.KeyManager;
65
import javax.net.ssl.KeyManagerFactory;
66
import javax.net.ssl.SSLContext;
67
import javax.net.ssl.SSLPeerUnverifiedException;
68
import javax.net.ssl.SSLServerSocket;
69
import javax.net.ssl.SSLSession;
70
import javax.net.ssl.SSLSocket;
71
import javax.net.ssl.TrustManagerFactory;
72
import javax.net.ssl.X509ExtendedKeyManager;
73
import javax.net.ssl.X509KeyManager;
74
import jdk.test.lib.security.SecurityUtils;
75
76
public class TLSWithEdDSA extends SSLSocketTemplate {
77
private static final String PASSWD = "passphrase";
78
private static final String DEF_TRUST_ANCHORS = "CA_DSA_1024:CA_DSA_2048:" +
79
"CA_ECDSA_SECP256R1:CA_ECDSA_SECP384R1:CA_ECDSA_SECP521R1:" +
80
"CA_ED25519:CA_ED448:CA_RSA_2048";
81
private static final String DEF_ALL_EE = "EE_ECDSA_SECP256R1:" +
82
"EE_ECDSA_SECP384R1:EE_ECDSA_SECP521R1:EE_RSA_2048:" +
83
"EE_EC_RSA_SECP256R1:EE_DSA_2048:EE_DSA_1024:EE_ED25519:EE_ED448";
84
private static final List<String> TEST_PROTOS = List.of(
85
"TLSv1.3", "TLSv1.2", "TLSv1.1", "TLSv1");
86
87
private static CertificateFactory certFac;
88
private static final Map<ParamType, String> clientParameters =
89
new HashMap<>();
90
private static final Map<ParamType, String> serverParameters =
91
new HashMap<>();
92
93
private final SessionChecker clientChecker;
94
private final SessionChecker serverChecker;
95
private final Class<? extends Throwable> clientException;
96
private final Class<? extends Throwable> serverException;
97
98
interface SessionChecker {
99
public void check(SSLSocket socket);
100
}
101
102
/**
103
* Checks to make sure the end-entity certificate presented by the
104
* peer uses and Ed25519 key.
105
*/
106
final static SessionChecker isPeerEd25519 = new SessionChecker() {
107
@Override
108
public void check(SSLSocket sock) {
109
try {
110
SSLSession session = sock.getSession();
111
System.out.println("Peer certificate check for Ed25519:\n" +
112
sessionDump(session));
113
Certificate[] serverCertChain = session.getPeerCertificates();
114
X509Certificate tlsCert = (X509Certificate)serverCertChain[0];
115
keyCheck(tlsCert.getPublicKey(), "EdDSA", "Ed25519");
116
} catch (SSLPeerUnverifiedException sslpe) {
117
throw new RuntimeException(sslpe);
118
}
119
}
120
};
121
122
/**
123
* Checks to make sure the end-entity certificate presented by the
124
* peer uses and Ed448 key.
125
*/
126
final static SessionChecker isPeerEd448 = new SessionChecker() {
127
@Override
128
public void check(SSLSocket sock) {
129
try {
130
SSLSession session = sock.getSession();
131
System.out.println("Peer certificate check for Ed448:\n" +
132
sessionDump(session));
133
Certificate[] serverCertChain = session.getPeerCertificates();
134
X509Certificate tlsCert = (X509Certificate)serverCertChain[0];
135
keyCheck(tlsCert.getPublicKey(), "EdDSA", "Ed448");
136
} catch (SSLPeerUnverifiedException sslpe) {
137
throw new RuntimeException(sslpe);
138
}
139
}
140
};
141
142
/**
143
* Checks to make sure the end-entity certificate presented by the
144
* peer uses an EC secp521r1 key.
145
*/
146
final static SessionChecker isPeerP521 = new SessionChecker() {
147
@Override
148
public void check(SSLSocket sock) {
149
try {
150
SSLSession session = sock.getSession();
151
System.out.println("Peer certificate check for secp521r1:\n" +
152
sessionDump(session));
153
Certificate[] serverCertChain = session.getPeerCertificates();
154
X509Certificate tlsCert = (X509Certificate)serverCertChain[0];
155
keyCheck(tlsCert.getPublicKey(), "EC", "secp521r1");
156
} catch (SSLPeerUnverifiedException sslpe) {
157
throw new RuntimeException(sslpe);
158
}
159
}
160
};
161
162
/**
163
* Returns a String summary of an SSLSession object
164
*
165
* @param sess the SSLSession object to be dumped
166
*
167
* @return a String representation of the test-relevant portions of the
168
* SSLSession object.
169
*/
170
private static String sessionDump(SSLSession sess) {
171
StringBuilder sb = new StringBuilder();
172
sb.append("----- Session Info -----\n");
173
sb.append("Protocol: ").append(sess.getProtocol()).append("\n");
174
sb.append("Cipher Suite: ").append(sess.getCipherSuite());
175
Certificate[] localCerts = sess.getLocalCertificates();
176
if (localCerts != null) {
177
sb.append("\nLocal Certs:");
178
int i = 0;
179
for (Certificate cert : localCerts) {
180
sb.append(String.format("\n [%d]: %s", i++,
181
((X509Certificate)cert).getSubjectX500Principal()));
182
}
183
}
184
try {
185
Certificate[] peerCerts = sess.getPeerCertificates();
186
if (peerCerts != null) {
187
sb.append("\nPeer Certs:");
188
int i = 0;
189
for (Certificate cert : peerCerts) {
190
sb.append(String.format("\n [%d]: %s", i++,
191
((X509Certificate)cert).getSubjectX500Principal()));
192
}
193
}
194
} catch (SSLPeerUnverifiedException sslex) {
195
throw new RuntimeException(sslex);
196
}
197
198
return sb.toString();
199
}
200
201
/**
202
* Checks to make sure the public key conforms to the expected key type
203
* and (where applicable) curve.
204
*
205
* @param pubKey the public key to be checked
206
* @param expPkType the expected key type (RSA/DSA/EC/EdDSA)
207
* @param expCurveName if an EC/EdDSA key, the expected curve
208
*/
209
private static void keyCheck(PublicKey pubKey, String expPkType,
210
String expCurveName) {
211
String curveName = null;
212
String pubKeyAlg = pubKey.getAlgorithm();
213
if (!expPkType.equalsIgnoreCase(pubKeyAlg)) {
214
throw new RuntimeException("Expected " + expPkType + " key, got " +
215
pubKeyAlg);
216
}
217
218
// Check the curve type
219
if (expCurveName != null) {
220
switch (pubKeyAlg) {
221
case "EdDSA":
222
curveName = ((EdECKey)pubKey).getParams().getName().
223
toLowerCase();
224
if (!expCurveName.equalsIgnoreCase(curveName)) {
225
throw new RuntimeException("Expected " + expCurveName +
226
" curve, " + "got " + curveName);
227
}
228
break;
229
case "EC":
230
curveName = ((ECKey)pubKey).getParams().toString().
231
toLowerCase();
232
if (!curveName.contains(expCurveName.toLowerCase())) {
233
throw new RuntimeException("Expected " + expCurveName +
234
" curve, " + "got " + curveName);
235
}
236
break;
237
default:
238
throw new IllegalArgumentException(
239
"Unsupported key type: " + pubKeyAlg);
240
}
241
}
242
System.out.format("Found key: %s / %s\n", pubKeyAlg,
243
curveName != null ? curveName : "");
244
}
245
246
TLSWithEdDSA(SessionChecker cliChk, Class<? extends Throwable> cliExpExc,
247
SessionChecker servChk, Class<? extends Throwable> servExpExc) {
248
super();
249
clientChecker = cliChk;
250
clientException = cliExpExc;
251
serverChecker = servChk;
252
serverException = servExpExc;
253
}
254
255
/**
256
* Creates an SSLContext for use with the client side of this test. This
257
* uses parameters held in the static client parameters map.
258
*
259
* @return an initialized SSLContext for use with the client.
260
*
261
* @throws Exception if any downstream errors occur during key store
262
* creation, key/trust manager factory creation or context
263
* initialization.
264
*/
265
@Override
266
protected SSLContext createClientSSLContext() throws Exception {
267
KeyStore clientKeyStore = createKeyStore(
268
clientParameters.getOrDefault(ParamType.KSENTRIES, ""),
269
PASSWD.toCharArray());
270
KeyStore clientTrustStore = createTrustStore(
271
clientParameters.getOrDefault(ParamType.TSENTRIES,
272
DEF_TRUST_ANCHORS));
273
return createCtxCommon(clientKeyStore,
274
clientParameters.get(ParamType.CERTALIAS), PASSWD.toCharArray(),
275
clientTrustStore, "jdk.tls.client.SignatureSchemes",
276
clientParameters.get(ParamType.SIGALGS));
277
}
278
279
/**
280
* Creates an SSLContext for use with the server side of this test. This
281
* uses parameters held in the static server parameters map.
282
*
283
* @return an initialized SSLContext for use with the server.
284
*
285
* @throws Exception if any downstream errors occur during key store
286
* creation, key/trust manager factory creation or context
287
* initialization.
288
*/
289
@Override
290
protected SSLContext createServerSSLContext() throws Exception {
291
KeyStore serverKeyStore = createKeyStore(
292
serverParameters.getOrDefault(ParamType.KSENTRIES, ""),
293
PASSWD.toCharArray());
294
KeyStore serverTrustStore = createTrustStore(
295
serverParameters.getOrDefault(ParamType.TSENTRIES,
296
DEF_TRUST_ANCHORS));
297
return createCtxCommon(serverKeyStore,
298
serverParameters.get(ParamType.CERTALIAS), PASSWD.toCharArray(),
299
serverTrustStore, "jdk.tls.server.SignatureSchemes",
300
serverParameters.get(ParamType.SIGALGS));
301
}
302
303
/**
304
* Create a trust store containing any CA certificates designated as
305
* trust anchors.
306
*
307
* @return the trust store populated with the root CA certificate.
308
*
309
* @throws GeneralSecurityException if any certificates cannot be added to
310
* the key store.
311
*/
312
private static KeyStore createTrustStore(String certEnumNames)
313
throws GeneralSecurityException {
314
KeyStore.Builder keyStoreBuilder =
315
KeyStore.Builder.newInstance("PKCS12", null,
316
new KeyStore.PasswordProtection(PASSWD.toCharArray()));
317
KeyStore ks = keyStoreBuilder.getKeyStore();
318
for (String certName : certEnumNames.split(":")) {
319
try {
320
SSLSocketTemplate.Cert cert =
321
SSLSocketTemplate.Cert.valueOf(certName);
322
ks.setCertificateEntry(certName, pem2Cert(cert.certStr));
323
} catch (IllegalArgumentException iae) {
324
System.out.println("Unable to find Cert enum entry for " +
325
certName + ", skipping");
326
}
327
}
328
return ks;
329
}
330
331
/**
332
* Create a key store containing any end-entity private keys/certs
333
* specified in the parameters.
334
*
335
* @param certEnumNames a colon-delimited list of String values that are
336
* the names of the SSLSocketTemplate.Cert enumeration entries.
337
* @param pass the desired password for the resulting KeyStore object.
338
*
339
* @return a populated, loaded KeyStore ready for use.
340
*
341
* @throws GeneralSecurityException if any issues occur while setting
342
* the private key or certificate entries.
343
*/
344
private static KeyStore createKeyStore(String certEnumNames, char[] pass)
345
throws GeneralSecurityException {
346
KeyStore.Builder keyStoreBuilder =
347
KeyStore.Builder.newInstance("PKCS12", null,
348
new KeyStore.PasswordProtection(pass));
349
KeyStore ks = keyStoreBuilder.getKeyStore();
350
if (certEnumNames != null && !certEnumNames.isEmpty()) {
351
for (String certName : certEnumNames.split(":")) {
352
try {
353
SSLSocketTemplate.Cert cert =
354
SSLSocketTemplate.Cert.valueOf(certName);
355
ks.setKeyEntry(certName,
356
pem2PrivKey(cert.privKeyStr, cert.keyAlgo), pass,
357
new Certificate[] { pem2Cert(cert.certStr) });
358
} catch (IllegalArgumentException iae) {
359
System.out.println("Unable to find Cert enum entry for " +
360
certName + ", skipping");
361
}
362
}
363
}
364
365
return ks;
366
}
367
368
/**
369
* Covert a PEM-encoded certificate into a X509Certificate object.
370
*
371
* @param certPem the PEM encoding for the certificate.
372
*
373
* @return the corresponding X509Certificate object for the provided PEM.
374
*
375
* @throws CertificateException if any decoding errors occur.
376
*/
377
private static X509Certificate pem2Cert(String certPem)
378
throws CertificateException {
379
return (X509Certificate)certFac.generateCertificate(
380
new ByteArrayInputStream(certPem.getBytes(
381
Charset.forName("UTF-8"))));
382
}
383
384
/**
385
* Covert a PEM-encoded PKCS8 private key into a PrivateKey object.
386
*
387
* @param keyPem the PEM encoding for the certificate.
388
* @param keyAlg the algorithm for the private key contained in the PKCS8
389
* ` encoding.
390
*
391
* @return the corresponding PrivateKey object for the provided PEM.
392
*
393
* @throws GeneralSecurityException if any decoding errors occur.
394
*/
395
private static PrivateKey pem2PrivKey(String keyPem, String keyAlg)
396
throws GeneralSecurityException {
397
PKCS8EncodedKeySpec p8Spec = new PKCS8EncodedKeySpec(
398
Base64.getMimeDecoder().decode(keyPem));
399
KeyFactory keyFac = KeyFactory.getInstance(keyAlg);
400
return keyFac.generatePrivate(p8Spec);
401
}
402
403
/**
404
* Create an SSLContext for use with the client or server sides of this
405
* test.
406
*
407
* @param keys the key store object for this SSLContext.
408
* @param alias optional alias specifier to exclusively use that alias for
409
* TLS connections.
410
* @param pass the key store password
411
* @param trust the trust store object
412
* @param sigAlgProp the signature algorithm property name to set
413
* (reserved for future use pending the fix for JDK-8255867)
414
* @param sigAlgVal the property value to be applied.
415
*
416
* @return an initialized SSLContext object.
417
*
418
* @throws IOException if any IOExceptions during manager factory creation
419
* take place
420
* @throws GeneralSecurityException any other failure during SSLContext
421
* creation/initialization
422
*/
423
private static SSLContext createCtxCommon(KeyStore keys, String alias,
424
char[] pass, KeyStore trust, String sigAlgProp, String sigAlgVal)
425
throws IOException, GeneralSecurityException {
426
SSLContext ctx;
427
if (sigAlgVal != null && !sigAlgVal.isEmpty()) {
428
System.setProperty(sigAlgProp, sigAlgVal);
429
}
430
431
// If an alias is specified use our local AliasKeyManager
432
KeyManager[] kms = (alias != null && !alias.isEmpty()) ?
433
new KeyManager[] { new AliasKeyManager(keys, pass, alias) } :
434
createKeyManagerFactory(keys, pass).getKeyManagers();
435
436
ctx = SSLContext.getInstance("TLS");
437
ctx.init(kms, createTrustManagerFactory(trust).getTrustManagers(),
438
null);
439
return ctx;
440
}
441
442
/**
443
* Creates a KeyManagerFactory for use during SSLContext initialization.
444
*
445
* @param ks the KeyStore forming the base of the KeyManagerFactory
446
* @param passwd the password to use for the key store
447
*
448
* @return the initialized KeyManagerFactory
449
*
450
* @throws IOException any IOExceptions during key manager factory
451
* initialization.
452
* @throws GeneralSecurityException if any failures during instantiation
453
* take place.
454
*/
455
private static KeyManagerFactory createKeyManagerFactory(KeyStore ks,
456
char[] passwd) throws IOException, GeneralSecurityException {
457
KeyManagerFactory kmf;
458
kmf = KeyManagerFactory.getInstance("SunX509");
459
kmf.init(ks, passwd);
460
461
KeyManager[] kmgrs = kmf.getKeyManagers();
462
X509ExtendedKeyManager xkm = (X509ExtendedKeyManager)kmgrs[0];
463
return kmf;
464
}
465
466
/**
467
* Creates a TrustManagerFactory for use during SSLContext initialization.
468
*
469
* @param trustStrore the KeyStore forming the base of the
470
* TrustManagerFactory
471
*
472
* @return the initialized TrustManagerFactory
473
*
474
* @throws IOException any IOExceptions during trust manager factory
475
* initialization.
476
* @throws GeneralSecurityException if any failures during instantiation
477
* take place.
478
*/
479
private static TrustManagerFactory createTrustManagerFactory(
480
KeyStore trustStore) throws IOException, GeneralSecurityException {
481
TrustManagerFactory tmf;
482
PKIXBuilderParameters pkixParams =
483
new PKIXBuilderParameters(trustStore, new X509CertSelector());
484
pkixParams.setRevocationEnabled(false);
485
tmf = TrustManagerFactory.getInstance("PKIX");
486
tmf.init(new CertPathTrustManagerParameters(pkixParams));
487
return tmf;
488
}
489
490
/*
491
* Configure the client side socket.
492
*/
493
@Override
494
protected void configureClientSocket(SSLSocket socket) {
495
String pVal;
496
if ((pVal = clientParameters.get(ParamType.PROTOS)) != null) {
497
socket.setEnabledProtocols(pVal.split(":"));
498
}
499
500
if ((pVal = clientParameters.get(ParamType.CIPHERS)) != null) {
501
socket.setEnabledCipherSuites(pVal.split(":"));
502
}
503
}
504
505
/*
506
* Configure the server side socket.
507
*/
508
@Override
509
protected void configureServerSocket(SSLServerSocket socket) {
510
String pVal;
511
try {
512
socket.setReuseAddress(true);
513
if ((pVal = serverParameters.get(ParamType.PROTOS)) != null) {
514
socket.setEnabledProtocols(pVal.split(":"));
515
}
516
517
if ((pVal = serverParameters.get(ParamType.CIPHERS)) != null) {
518
socket.setEnabledCipherSuites(pVal.split(":"));
519
}
520
521
pVal = serverParameters.get(ParamType.CLIAUTH);
522
socket.setWantClientAuth("WANT".equalsIgnoreCase(pVal));
523
socket.setNeedClientAuth("NEED".equalsIgnoreCase(pVal));
524
} catch (SocketException se) {
525
throw new RuntimeException(se);
526
}
527
}
528
529
530
@Override
531
protected void runServerApplication(SSLSocket socket) throws Exception {
532
InputStream sslIS = socket.getInputStream();
533
OutputStream sslOS = socket.getOutputStream();
534
535
sslIS.read();
536
sslOS.write(85);
537
sslOS.flush();
538
539
if (serverChecker != null) {
540
serverChecker.check(socket);
541
}
542
}
543
544
@Override
545
protected void runClientApplication(SSLSocket socket) throws Exception {
546
InputStream sslIS = socket.getInputStream();
547
OutputStream sslOS = socket.getOutputStream();
548
549
sslOS.write(280);
550
sslOS.flush();
551
sslIS.read();
552
553
if (clientChecker != null) {
554
clientChecker.check(socket);
555
}
556
}
557
558
public static void main(String[] args) throws Exception {
559
SecurityUtils.removeFromDisabledTlsAlgs("TLSv1.1", "TLSv1");
560
certFac = CertificateFactory.getInstance("X.509");
561
String testFormat;
562
563
System.out.println("===== Test KeyManager alias retrieval =====");
564
testKeyManager(DEF_ALL_EE, "EdDSA",
565
new String[] {"ee_ed25519", "ee_ed448"});
566
567
testFormat =
568
"===== Basic Ed25519 Server-side Authentication: %s =====\n";
569
serverParameters.put(ParamType.KSENTRIES, "EE_ED25519:EE_RSA_2048");
570
runtest(testFormat, isPeerEd25519, null, null, null);
571
572
testFormat =
573
"===== Basic Ed448 Server-side Authentication: %s =====\n";
574
serverParameters.put(ParamType.KSENTRIES, "EE_ED448:EE_RSA_2048");
575
runtest(testFormat, isPeerEd448, null, null, null);
576
577
testFormat = "===== EC favored over EdDSA by default: %s =====\n";
578
serverParameters.put(ParamType.KSENTRIES,
579
"EE_ED25519:EE_ECDSA_SECP521R1");
580
runtest(testFormat, isPeerP521, null, null, null);
581
582
testFormat = "===== Override EC favoring by alias: %s =====\n";
583
serverParameters.put(ParamType.CERTALIAS, "EE_ED25519");
584
runtest(testFormat, isPeerEd25519, null, null, null);
585
serverParameters.remove(ParamType.CERTALIAS);
586
587
testFormat = "===== EdDSA Client Authentication: %s =====\n";
588
serverParameters.put(ParamType.KSENTRIES, "EE_RSA_2048");
589
serverParameters.put(ParamType.CLIAUTH, "NEED");
590
clientParameters.put(ParamType.KSENTRIES, "EE_ED25519");
591
runtest(testFormat, null, null, isPeerEd25519, null);
592
}
593
594
private static void testKeyManager(String keyStoreSpec, String keyType,
595
String[] expAliases)
596
throws GeneralSecurityException, IOException {
597
char[] passChar = PASSWD.toCharArray();
598
599
// Create the KeyManager factory and resulting KeyManager
600
KeyManagerFactory kmf = createKeyManagerFactory(
601
createKeyStore(keyStoreSpec, passChar), passChar);
602
KeyManager[] kMgrs = kmf.getKeyManagers();
603
X509KeyManager xkm = (X509KeyManager)kMgrs[0];
604
605
String[] cliEdDSAAlises = xkm.getClientAliases(keyType, null);
606
System.out.format("Client Aliases (%s): ", keyType);
607
for (String alias : cliEdDSAAlises) {
608
System.out.print(alias + " ");
609
}
610
System.out.println();
611
612
String[] servEdDSAAliases = xkm.getServerAliases(keyType, null);
613
System.out.format("Server Aliases (%s): ", keyType);
614
for (String alias : servEdDSAAliases) {
615
System.out.print(alias + " ");
616
}
617
System.out.println();
618
619
if (!Arrays.equals(cliEdDSAAlises, expAliases)) {
620
throw new RuntimeException("Client alias mismatch");
621
} else if (!Arrays.equals(servEdDSAAliases, expAliases)) {
622
throw new RuntimeException("Server alias mismatch");
623
}
624
}
625
626
private static void runtest(String testNameFmt, SessionChecker cliChk,
627
Class<? extends Throwable> cliExpExc, SessionChecker servChk,
628
Class<? extends Throwable> servExpExc) {
629
TEST_PROTOS.forEach(protocol -> {
630
clientParameters.put(ParamType.PROTOS, protocol);
631
TLSWithEdDSA testObj = new TLSWithEdDSA(cliChk, cliExpExc, servChk,
632
servExpExc);
633
System.out.format(testNameFmt, protocol);
634
try {
635
testObj.run();
636
if (testObj.clientException != null ||
637
testObj.serverException != null) {
638
throw new RuntimeException("Expected exception from " +
639
"either client or server but was missed");
640
}
641
} catch (Exception exc) {
642
if (testObj.clientException == null &&
643
testObj.serverException == null) {
644
throw new RuntimeException(
645
"Expected test failure did not occur");
646
} else if (testObj.clientException != null &&
647
!testObj.clientException.isAssignableFrom(exc.getClass())) {
648
throw new RuntimeException("Unexpected client exception " +
649
"detected: Expected " +
650
testObj.clientException.getName() +
651
", got " + exc.getClass().getName());
652
653
} else if (testObj.serverException != null &&
654
!testObj.serverException.isAssignableFrom(exc.getClass())) {
655
throw new RuntimeException("Unexpected client exception " +
656
"detected: Expected " +
657
testObj.serverException.getName() +
658
", got " + exc.getClass().getName());
659
}
660
}
661
System.out.println();
662
});
663
}
664
665
/**
666
* A Custom KeyManager that allows the user to specify a key/certificate
667
* by alias to be used for any TLS authentication actions.
668
*/
669
static class AliasKeyManager implements X509KeyManager {
670
private final String alias;
671
private final KeyStore keystore;
672
private final char[] pass;
673
674
public AliasKeyManager(KeyStore keystore, char[] pass, String alias) {
675
this.keystore = Objects.requireNonNull(keystore);
676
this.alias = Objects.requireNonNull(alias);
677
this.pass = Objects.requireNonNull(pass);
678
}
679
680
@Override
681
public PrivateKey getPrivateKey(String alias) {
682
try {
683
return (PrivateKey)keystore.getKey(alias, pass);
684
} catch (GeneralSecurityException exc) {
685
throw new RuntimeException(exc);
686
}
687
}
688
689
@Override
690
public X509Certificate[] getCertificateChain(String alias) {
691
try {
692
Certificate[] certAr = keystore.getCertificateChain(alias);
693
return (certAr != null) ? Arrays.copyOf(certAr, certAr.length,
694
X509Certificate[].class) : null;
695
} catch (KeyStoreException ke) {
696
throw new RuntimeException(ke);
697
}
698
}
699
700
@Override
701
public String chooseClientAlias(String[] keyType, Principal[] issuers,
702
Socket socket) {
703
// Blindly return the one selected alias.
704
return alias;
705
}
706
707
@Override
708
public String chooseServerAlias(String keyType, Principal[] issuers,
709
Socket socket) {
710
// Blindly return the one selected alias.
711
return alias;
712
}
713
714
@Override
715
public String[] getClientAliases(String keyType, Principal[] issuers) {
716
// There can be only one!
717
return new String[] { alias };
718
}
719
720
@Override
721
public String[] getServerAliases(String keyType, Principal[] issuers) {
722
// There can be only one!
723
return new String[] { alias };
724
}
725
}
726
727
static enum ParamType {
728
PROTOS,
729
CIPHERS,
730
SIGALGS,
731
CLIAUTH,
732
KSENTRIES,
733
TSENTRIES,
734
CERTALIAS
735
}
736
}
737