Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/sun/security/pkcs11/tls/tls12/FipsModeTLS12.java
41161 views
1
/*
2
* Copyright (c) 2019, Red Hat, Inc.
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
* @test
26
* @bug 8029661
27
* @summary Test TLS 1.2
28
* @modules java.base/sun.security.internal.spec
29
* java.base/sun.security.util
30
* java.base/com.sun.crypto.provider
31
* @library /test/lib ../..
32
* @run main/othervm/timeout=120 -Djdk.tls.useExtendedMasterSecret=false FipsModeTLS12
33
*/
34
35
import java.io.File;
36
import java.io.FileInputStream;
37
import java.io.InputStream;
38
import java.nio.ByteBuffer;
39
40
import java.security.PrivateKey;
41
import java.security.PublicKey;
42
import java.security.KeyStore;
43
import java.security.NoSuchAlgorithmException;
44
import java.security.Provider;
45
import java.security.SecureRandom;
46
import java.security.Security;
47
48
import java.util.Arrays;
49
import java.util.LinkedList;
50
import java.util.List;
51
52
import javax.crypto.Cipher;
53
import javax.crypto.KeyGenerator;
54
import javax.crypto.SecretKey;
55
import javax.crypto.spec.SecretKeySpec;
56
57
import javax.net.ssl.KeyManagerFactory;
58
import javax.net.ssl.SSLContext;
59
import javax.net.ssl.SSLEngine;
60
import javax.net.ssl.SSLEngineResult;
61
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
62
import javax.net.ssl.SSLParameters;
63
import javax.net.ssl.SSLSession;
64
import javax.net.ssl.TrustManagerFactory;
65
66
import sun.security.internal.spec.TlsMasterSecretParameterSpec;
67
import sun.security.internal.spec.TlsPrfParameterSpec;
68
import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
69
70
public final class FipsModeTLS12 extends SecmodTest {
71
72
private static final boolean enableDebug = true;
73
74
private static Provider sunPKCS11NSSProvider;
75
private static Provider sunJCEProvider;
76
private static KeyStore ks;
77
private static KeyStore ts;
78
private static char[] passphrase = "JAHshj131@@".toCharArray();
79
private static PrivateKey privateKey;
80
private static PublicKey publicKey;
81
82
public static void main(String[] args) throws Exception {
83
try {
84
initialize();
85
} catch (Exception e) {
86
System.out.println("Test skipped: failure during" +
87
" initialization");
88
if (enableDebug) {
89
System.out.println(e);
90
}
91
return;
92
}
93
94
if (shouldRun()) {
95
// Test against JCE
96
testTlsAuthenticationCodeGeneration();
97
98
// Self-integrity test (complete TLS 1.2 communication)
99
new testTLS12SunPKCS11Communication().run();
100
101
System.out.println("Test PASS - OK");
102
} else {
103
System.out.println("Test skipped: TLS 1.2 mechanisms" +
104
" not supported by current SunPKCS11 back-end");
105
}
106
}
107
108
private static boolean shouldRun() {
109
if (sunPKCS11NSSProvider == null) {
110
return false;
111
}
112
try {
113
KeyGenerator.getInstance("SunTls12MasterSecret",
114
sunPKCS11NSSProvider);
115
KeyGenerator.getInstance(
116
"SunTls12RsaPremasterSecret", sunPKCS11NSSProvider);
117
KeyGenerator.getInstance("SunTls12Prf", sunPKCS11NSSProvider);
118
} catch (NoSuchAlgorithmException e) {
119
return false;
120
}
121
return true;
122
}
123
124
private static void testTlsAuthenticationCodeGeneration()
125
throws Exception {
126
// Generate RSA Pre-Master Secret in SunPKCS11 provider
127
SecretKey rsaPreMasterSecret = null;
128
@SuppressWarnings("deprecation")
129
TlsRsaPremasterSecretParameterSpec rsaPreMasterSecretSpec =
130
new TlsRsaPremasterSecretParameterSpec(0x0303, 0x0303);
131
{
132
KeyGenerator rsaPreMasterSecretKG = KeyGenerator.getInstance(
133
"SunTls12RsaPremasterSecret", sunPKCS11NSSProvider);
134
rsaPreMasterSecretKG.init(rsaPreMasterSecretSpec, null);
135
rsaPreMasterSecret = rsaPreMasterSecretKG.generateKey();
136
}
137
138
// Get RSA Pre-Master Secret in plain (from SunPKCS11 provider)
139
byte[] rsaPlainPreMasterSecret = null;
140
{
141
Cipher rsaPreMasterSecretWrapperCipher =
142
Cipher.getInstance("RSA/ECB/PKCS1Padding",
143
sunPKCS11NSSProvider);
144
rsaPreMasterSecretWrapperCipher.init(Cipher.WRAP_MODE, publicKey,
145
new SecureRandom());
146
byte[] rsaEncryptedPreMasterSecret =
147
rsaPreMasterSecretWrapperCipher.wrap(rsaPreMasterSecret);
148
Cipher rsaPreMasterSecretUnwrapperCipher =
149
Cipher.getInstance("RSA/ECB/PKCS1Padding", sunJCEProvider);
150
rsaPreMasterSecretUnwrapperCipher.init(Cipher.UNWRAP_MODE,
151
privateKey, rsaPreMasterSecretSpec);
152
rsaPlainPreMasterSecret = rsaPreMasterSecretUnwrapperCipher.unwrap(
153
rsaEncryptedPreMasterSecret, "TlsRsaPremasterSecret",
154
Cipher.SECRET_KEY).getEncoded();
155
156
if (enableDebug) {
157
System.out.println("rsaPlainPreMasterSecret:");
158
for (byte b : rsaPlainPreMasterSecret) {
159
System.out.printf("%02X, ", b);
160
}
161
System.out.println("");
162
}
163
}
164
165
// Generate Master Secret
166
SecretKey sunPKCS11MasterSecret = null;
167
SecretKey jceMasterSecret = null;
168
{
169
KeyGenerator sunPKCS11MasterSecretGenerator =
170
KeyGenerator.getInstance("SunTls12MasterSecret",
171
sunPKCS11NSSProvider);
172
KeyGenerator jceMasterSecretGenerator = KeyGenerator.getInstance(
173
"SunTls12MasterSecret", sunJCEProvider);
174
@SuppressWarnings("deprecation")
175
TlsMasterSecretParameterSpec sunPKCS11MasterSecretSpec =
176
new TlsMasterSecretParameterSpec(rsaPreMasterSecret, 3, 3,
177
new byte[32], new byte[32], "SHA-256", 32, 64);
178
@SuppressWarnings("deprecation")
179
TlsMasterSecretParameterSpec jceMasterSecretSpec =
180
new TlsMasterSecretParameterSpec(
181
new SecretKeySpec(rsaPlainPreMasterSecret,
182
"Generic"), 3, 3, new byte[32],
183
new byte[32], "SHA-256", 32, 64);
184
sunPKCS11MasterSecretGenerator.init(sunPKCS11MasterSecretSpec,
185
null);
186
jceMasterSecretGenerator.init(jceMasterSecretSpec, null);
187
sunPKCS11MasterSecret =
188
sunPKCS11MasterSecretGenerator.generateKey();
189
jceMasterSecret = jceMasterSecretGenerator.generateKey();
190
if (enableDebug) {
191
System.out.println("Master Secret (SunJCE):");
192
if (jceMasterSecret != null) {
193
for (byte b : jceMasterSecret.getEncoded()) {
194
System.out.printf("%02X, ", b);
195
}
196
System.out.println("");
197
}
198
}
199
}
200
201
// Generate authentication codes
202
byte[] sunPKCS11AuthenticationCode = null;
203
byte[] jceAuthenticationCode = null;
204
{
205
// Generate SunPKCS11 authentication code
206
{
207
@SuppressWarnings("deprecation")
208
TlsPrfParameterSpec sunPKCS11AuthenticationCodeSpec =
209
new TlsPrfParameterSpec(sunPKCS11MasterSecret,
210
"client finished", "a".getBytes(), 12,
211
"SHA-256", 32, 64);
212
KeyGenerator sunPKCS11AuthCodeGenerator =
213
KeyGenerator.getInstance("SunTls12Prf",
214
sunPKCS11NSSProvider);
215
sunPKCS11AuthCodeGenerator.init(
216
sunPKCS11AuthenticationCodeSpec);
217
sunPKCS11AuthenticationCode =
218
sunPKCS11AuthCodeGenerator.generateKey().getEncoded();
219
}
220
221
// Generate SunJCE authentication code
222
{
223
@SuppressWarnings("deprecation")
224
TlsPrfParameterSpec jceAuthenticationCodeSpec =
225
new TlsPrfParameterSpec(jceMasterSecret,
226
"client finished", "a".getBytes(), 12,
227
"SHA-256", 32, 64);
228
KeyGenerator jceAuthCodeGenerator =
229
KeyGenerator.getInstance("SunTls12Prf",
230
sunJCEProvider);
231
jceAuthCodeGenerator.init(jceAuthenticationCodeSpec);
232
jceAuthenticationCode =
233
jceAuthCodeGenerator.generateKey().getEncoded();
234
}
235
236
if (enableDebug) {
237
System.out.println("SunPKCS11 Authentication Code: ");
238
for (byte b : sunPKCS11AuthenticationCode) {
239
System.out.printf("%02X, ", b);
240
}
241
System.out.println("");
242
System.out.println("SunJCE Authentication Code: ");
243
for (byte b : jceAuthenticationCode) {
244
System.out.printf("%02X, ", b);
245
}
246
System.out.println("");
247
}
248
}
249
250
if (sunPKCS11AuthenticationCode == null ||
251
jceAuthenticationCode == null ||
252
sunPKCS11AuthenticationCode.length == 0 ||
253
jceAuthenticationCode.length == 0 ||
254
!Arrays.equals(sunPKCS11AuthenticationCode,
255
jceAuthenticationCode)) {
256
throw new Exception("Authentication codes from JCE" +
257
" and SunPKCS11 differ.");
258
}
259
}
260
261
private static class testTLS12SunPKCS11Communication {
262
public static void run() throws Exception {
263
SSLEngine[][] enginesToTest = getSSLEnginesToTest();
264
265
for (SSLEngine[] engineToTest : enginesToTest) {
266
267
SSLEngine clientSSLEngine = engineToTest[0];
268
SSLEngine serverSSLEngine = engineToTest[1];
269
270
// SSLEngine code based on RedhandshakeFinished.java
271
272
boolean dataDone = false;
273
274
ByteBuffer clientOut = null;
275
ByteBuffer clientIn = null;
276
ByteBuffer serverOut = null;
277
ByteBuffer serverIn = null;
278
ByteBuffer cTOs;
279
ByteBuffer sTOc;
280
281
SSLSession session = clientSSLEngine.getSession();
282
int appBufferMax = session.getApplicationBufferSize();
283
int netBufferMax = session.getPacketBufferSize();
284
285
clientIn = ByteBuffer.allocate(appBufferMax + 50);
286
serverIn = ByteBuffer.allocate(appBufferMax + 50);
287
288
cTOs = ByteBuffer.allocateDirect(netBufferMax);
289
sTOc = ByteBuffer.allocateDirect(netBufferMax);
290
291
clientOut = ByteBuffer.wrap(
292
"Hi Server, I'm Client".getBytes());
293
serverOut = ByteBuffer.wrap(
294
"Hello Client, I'm Server".getBytes());
295
296
SSLEngineResult clientResult;
297
SSLEngineResult serverResult;
298
299
while (!dataDone) {
300
clientResult = clientSSLEngine.wrap(clientOut, cTOs);
301
runDelegatedTasks(clientResult, clientSSLEngine);
302
serverResult = serverSSLEngine.wrap(serverOut, sTOc);
303
runDelegatedTasks(serverResult, serverSSLEngine);
304
cTOs.flip();
305
sTOc.flip();
306
307
if (enableDebug) {
308
System.out.println("Client -> Network");
309
printTlsNetworkPacket("", cTOs);
310
System.out.println("");
311
System.out.println("Server -> Network");
312
printTlsNetworkPacket("", sTOc);
313
System.out.println("");
314
}
315
316
clientResult = clientSSLEngine.unwrap(sTOc, clientIn);
317
runDelegatedTasks(clientResult, clientSSLEngine);
318
serverResult = serverSSLEngine.unwrap(cTOs, serverIn);
319
runDelegatedTasks(serverResult, serverSSLEngine);
320
321
cTOs.compact();
322
sTOc.compact();
323
324
if (!dataDone &&
325
(clientOut.limit() == serverIn.position()) &&
326
(serverOut.limit() == clientIn.position())) {
327
checkTransfer(serverOut, clientIn);
328
checkTransfer(clientOut, serverIn);
329
dataDone = true;
330
}
331
}
332
}
333
}
334
335
static void printTlsNetworkPacket(String prefix, ByteBuffer bb) {
336
ByteBuffer slice = bb.slice();
337
byte[] buffer = new byte[slice.remaining()];
338
slice.get(buffer);
339
for (int i = 0; i < buffer.length; i++) {
340
System.out.printf("%02X, ", (byte)(buffer[i] & (byte)0xFF));
341
if (i % 8 == 0 && i % 16 != 0) {
342
System.out.print(" ");
343
}
344
if (i % 16 == 0) {
345
System.out.println("");
346
}
347
}
348
System.out.flush();
349
}
350
351
private static void checkTransfer(ByteBuffer a, ByteBuffer b)
352
throws Exception {
353
a.flip();
354
b.flip();
355
if (!a.equals(b)) {
356
throw new Exception("Data didn't transfer cleanly");
357
}
358
a.position(a.limit());
359
b.position(b.limit());
360
a.limit(a.capacity());
361
b.limit(b.capacity());
362
}
363
364
private static void runDelegatedTasks(SSLEngineResult result,
365
SSLEngine engine) throws Exception {
366
367
if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
368
Runnable runnable;
369
while ((runnable = engine.getDelegatedTask()) != null) {
370
runnable.run();
371
}
372
HandshakeStatus hsStatus = engine.getHandshakeStatus();
373
if (hsStatus == HandshakeStatus.NEED_TASK) {
374
throw new Exception(
375
"handshake shouldn't need additional tasks");
376
}
377
}
378
}
379
380
private static SSLEngine[][] getSSLEnginesToTest() throws Exception {
381
SSLEngine[][] enginesToTest = new SSLEngine[2][2];
382
// TLS_RSA_WITH_AES_128_GCM_SHA256 ciphersuite is available but
383
// must not be chosen for the TLS connection if not supported.
384
// See JDK-8222937.
385
String[][] preferredSuites = new String[][]{ new String[] {
386
"TLS_RSA_WITH_AES_128_GCM_SHA256",
387
"TLS_RSA_WITH_AES_128_CBC_SHA256"
388
}, new String[] {
389
"TLS_RSA_WITH_AES_128_GCM_SHA256",
390
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"
391
}};
392
for (int i = 0; i < enginesToTest.length; i++) {
393
enginesToTest[i][0] = createSSLEngine(true);
394
enginesToTest[i][1] = createSSLEngine(false);
395
// All CipherSuites enabled for the client.
396
enginesToTest[i][1].setEnabledCipherSuites(preferredSuites[i]);
397
}
398
return enginesToTest;
399
}
400
401
static private SSLEngine createSSLEngine(boolean client)
402
throws Exception {
403
SSLEngine ssle;
404
KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX", "SunJSSE");
405
kmf.init(ks, passphrase);
406
407
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX", "SunJSSE");
408
tmf.init(ts);
409
410
SSLContext sslCtx = SSLContext.getInstance("TLSv1.2", "SunJSSE");
411
sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
412
ssle = sslCtx.createSSLEngine("localhost", 443);
413
ssle.setUseClientMode(client);
414
SSLParameters sslParameters = ssle.getSSLParameters();
415
ssle.setSSLParameters(sslParameters);
416
417
return ssle;
418
}
419
}
420
421
private static void initialize() throws Exception {
422
//
423
// For a successful FIPS-mode TLS connection, the following
424
// cryptographic providers will be installed:
425
//
426
// 1. SunPKCS11 (with an NSS FIPS mode backend)
427
// 2. SUN (to handle X.509 certificates)
428
// 3. SunJSSE (for a TLS engine)
429
//
430
// RSASSA-PSS algorithm is not currently supported in SunPKCS11
431
// but in SUN provider. As a result, it can be negotiated by the
432
// TLS engine. The problem is that SunPKCS11 keys are sensitive
433
// in FIPS mode and cannot be used in a SUN algorithm (conversion
434
// fails as plain values cannot be extracted).
435
//
436
// To workaround this issue, we disable RSASSA-PSS algorithm for
437
// TLS connections. Once JDK-8222937 is fixed, this workaround can
438
// (and should) be removed.
439
//
440
// On a final note, the list of disabled TLS algorithms
441
// (jdk.tls.disabledAlgorithms) has to be updated at this point,
442
// before it is read in sun.security.ssl.SSLAlgorithmConstraints
443
// class initialization.
444
String disabledAlgorithms =
445
Security.getProperty("jdk.tls.disabledAlgorithms");
446
if (disabledAlgorithms.length() > 0) {
447
disabledAlgorithms += ", ";
448
}
449
disabledAlgorithms += "RSASSA-PSS";
450
Security.setProperty("jdk.tls.disabledAlgorithms", disabledAlgorithms);
451
452
if (initSecmod() == false) {
453
return;
454
}
455
String configName = BASE + SEP + "nss.cfg";
456
sunPKCS11NSSProvider = getSunPKCS11(configName);
457
System.out.println("SunPKCS11 provider: " + sunPKCS11NSSProvider);
458
459
List<Provider> installedProviders = new LinkedList<>();
460
for (Provider p : Security.getProviders()){
461
installedProviders.add(p);
462
Security.removeProvider(p.getName());
463
}
464
Security.addProvider(sunPKCS11NSSProvider);
465
for (Provider p : installedProviders){
466
String providerName = p.getName();
467
if (providerName.equals("SunJSSE") || providerName.equals("SUN")) {
468
Security.addProvider(p);
469
} else if (providerName.equals("SunJCE")) {
470
sunJCEProvider = p;
471
}
472
}
473
474
ks = KeyStore.getInstance("PKCS11", sunPKCS11NSSProvider);
475
ks.load(null, "test12".toCharArray());
476
ts = ks;
477
478
KeyStore ksPlain = readTestKeyStore();
479
privateKey = (PrivateKey)ksPlain.getKey("rh_rsa_sha256",
480
passphrase);
481
publicKey = (PublicKey)ksPlain.getCertificate(
482
"rh_rsa_sha256").getPublicKey();
483
}
484
485
private static KeyStore readTestKeyStore() throws Exception {
486
File file = new File(System.getProperty("test.src", "."), "keystore");
487
InputStream in = new FileInputStream(file);
488
KeyStore ks = KeyStore.getInstance("JKS");
489
ks.load(in, "passphrase".toCharArray());
490
in.close();
491
return ks;
492
}
493
}
494
495