Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java
41152 views
1
/*
2
* Copyright (c) 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 8145854 8153829
30
* @summary SSLContextImpl.statusResponseManager should be generated if required
31
* @library ../../../../java/security/testlibrary
32
* @build CertificateBuilder SimpleOCSPServer
33
* @run main/othervm StapleEnableProps
34
*/
35
36
import javax.net.ssl.*;
37
import javax.net.ssl.SSLEngineResult.*;
38
import java.io.*;
39
import java.math.BigInteger;
40
import java.security.*;
41
import java.nio.*;
42
import java.security.cert.X509Certificate;
43
import java.util.ArrayList;
44
import java.util.Collections;
45
import java.util.Date;
46
import java.util.HashMap;
47
import java.util.List;
48
import java.util.Map;
49
import java.util.Objects;
50
import java.util.concurrent.TimeUnit;
51
52
import sun.security.testlibrary.SimpleOCSPServer;
53
import sun.security.testlibrary.CertificateBuilder;
54
55
public class StapleEnableProps {
56
57
/*
58
* Enables logging of the SSLEngine operations.
59
*/
60
private static final boolean logging = true;
61
62
/*
63
* Enables the JSSE system debugging system property:
64
*
65
* -Djavax.net.debug=all
66
*
67
* This gives a lot of low-level information about operations underway,
68
* including specific handshake messages, and might be best examined
69
* after gaining some familiarity with this application.
70
*/
71
private static final boolean debug = false;
72
73
// These four ByteBuffer references will be used to hang onto ClientHello
74
// messages with and without the status_request[_v2] extensions. These
75
// will be used in the server-side stapling tests. There are two sets,
76
// one for 1.2 and earlier versions of the protocol and one for 1.3
77
// and later versions, since the handshake and extension sets differ
78
// between the two sets.
79
private static ByteBuffer cHello12Staple;
80
private static ByteBuffer cHello12NoStaple;
81
private static ByteBuffer cHello13Staple;
82
private static ByteBuffer cHello13NoStaple;
83
84
// The following items are used to set up the keystores.
85
private static final String passwd = "passphrase";
86
private static final String ROOT_ALIAS = "root";
87
private static final String INT_ALIAS = "intermediate";
88
private static final String SSL_ALIAS = "ssl";
89
90
// PKI components we will need for this test
91
private static KeyManagerFactory kmf;
92
private static TrustManagerFactory tmf;
93
private static KeyStore rootKeystore; // Root CA Keystore
94
private static KeyStore intKeystore; // Intermediate CA Keystore
95
private static KeyStore serverKeystore; // SSL Server Keystore
96
private static KeyStore trustStore; // SSL Client trust store
97
private static SimpleOCSPServer rootOcsp; // Root CA OCSP Responder
98
private static int rootOcspPort; // Port for root OCSP
99
private static SimpleOCSPServer intOcsp; // Intermediate CA OCSP server
100
private static int intOcspPort; // Port for intermediate OCSP
101
102
// Extra configuration parameters and constants
103
static final String[] TLS13ONLY = new String[] { "TLSv1.3" };
104
static final String[] TLS12MAX =
105
new String[] { "TLSv1.2", "TLSv1.1", "TLSv1" };
106
107
// A few helpful TLS definitions to make it easier
108
private static final int HELLO_EXT_STATUS_REQ = 5;
109
private static final int HELLO_EXT_STATUS_REQ_V2 = 17;
110
111
/*
112
* Main entry point for this test.
113
*/
114
public static void main(String args[]) throws Exception {
115
if (debug) {
116
System.setProperty("javax.net.debug", "ssl:handshake,verbose");
117
}
118
119
// Create the PKI we will use for the test and start the OCSP servers
120
createPKI();
121
122
// Set up the KeyManagerFactory and TrustManagerFactory
123
kmf = KeyManagerFactory.getInstance("PKIX");
124
kmf.init(serverKeystore, passwd.toCharArray());
125
tmf = TrustManagerFactory.getInstance("PKIX");
126
tmf.init(trustStore);
127
128
// Run the client and server property tests
129
testClientProp();
130
testServerProp();
131
132
}
133
134
private static void testClientProp() throws Exception {
135
SSLEngineResult clientResult;
136
137
// Test with the client-side enable property set to true
138
System.out.println("=========================================");
139
System.out.println("Client Test 1: " +
140
"jdk.tls.client.enableStatusRequestExtension = true");
141
System.out.println("Version = TLS 1.2");
142
System.out.println("=========================================");
143
144
System.setProperty("jdk.tls.client.enableStatusRequestExtension",
145
"true");
146
SSLContext ctxStaple = SSLContext.getInstance("TLS");
147
ctxStaple.init(null, tmf.getTrustManagers(), null);
148
SSLEngine engine = ctxStaple.createSSLEngine();
149
engine.setUseClientMode(true);
150
engine.setEnabledProtocols(TLS12MAX);
151
SSLSession session = engine.getSession();
152
ByteBuffer clientOut = ByteBuffer.wrap("I'm a Client".getBytes());
153
ByteBuffer cTOs =
154
ByteBuffer.allocateDirect(session.getPacketBufferSize());
155
156
// Create and check the ClientHello message
157
clientResult = engine.wrap(clientOut, cTOs);
158
log("client wrap: ", clientResult);
159
if (clientResult.getStatus() != SSLEngineResult.Status.OK) {
160
throw new SSLException("Client wrap got status: " +
161
clientResult.getStatus());
162
}
163
cTOs.flip();
164
System.out.println(dumpHexBytes(cTOs));
165
checkClientHello(cTOs, true, true);
166
cHello12Staple = cTOs;
167
168
// Test with the property set to false
169
System.out.println("=========================================");
170
System.out.println("Client Test 2: " +
171
"jdk.tls.client.enableStatusRequestExtension = false");
172
System.out.println("Version = TLS 1.2");
173
System.out.println("=========================================");
174
175
System.setProperty("jdk.tls.client.enableStatusRequestExtension",
176
"false");
177
SSLContext ctxNoStaple = SSLContext.getInstance("TLS");
178
ctxNoStaple.init(null, tmf.getTrustManagers(), null);
179
engine = ctxNoStaple.createSSLEngine();
180
engine.setUseClientMode(true);
181
engine.setEnabledProtocols(TLS12MAX);
182
session = engine.getSession();
183
cTOs = ByteBuffer.allocateDirect(session.getPacketBufferSize());
184
185
// Create and check the ClientHello message
186
clientResult = engine.wrap(clientOut, cTOs);
187
log("client wrap: ", clientResult);
188
if (clientResult.getStatus() != SSLEngineResult.Status.OK) {
189
throw new SSLException("Client wrap got status: " +
190
clientResult.getStatus());
191
}
192
cTOs.flip();
193
System.out.println(dumpHexBytes(cTOs));
194
checkClientHello(cTOs, false, false);
195
cHello12NoStaple = cTOs;
196
197
// Turn the property back on to true and test using TLS 1.3
198
System.out.println("=========================================");
199
System.out.println("Client Test 3: " +
200
"jdk.tls.client.enableStatusRequestExtension = true");
201
System.out.println("Version = TLS 1.3");
202
System.out.println("=========================================");
203
204
System.setProperty("jdk.tls.client.enableStatusRequestExtension",
205
"true");
206
ctxStaple = SSLContext.getInstance("TLS");
207
ctxStaple.init(null, tmf.getTrustManagers(), null);
208
engine = ctxStaple.createSSLEngine();
209
engine.setUseClientMode(true);
210
engine.setEnabledProtocols(TLS13ONLY);
211
session = engine.getSession();
212
cTOs = ByteBuffer.allocateDirect(session.getPacketBufferSize());
213
214
// Create and check the ClientHello message
215
clientResult = engine.wrap(clientOut, cTOs);
216
log("client wrap: ", clientResult);
217
if (clientResult.getStatus() != SSLEngineResult.Status.OK) {
218
throw new SSLException("Client wrap got status: " +
219
clientResult.getStatus());
220
}
221
cTOs.flip();
222
System.out.println(dumpHexBytes(cTOs));
223
checkClientHello(cTOs, true, false);
224
cHello13Staple = cTOs;
225
226
// Turn the property off again and test in a TLS 1.3 handshake
227
System.out.println("=========================================");
228
System.out.println("Client Test 4: " +
229
"jdk.tls.client.enableStatusRequestExtension = false");
230
System.out.println("Version = TLS 1.3");
231
System.out.println("=========================================");
232
233
System.setProperty("jdk.tls.client.enableStatusRequestExtension",
234
"false");
235
ctxNoStaple = SSLContext.getInstance("TLS");
236
ctxNoStaple.init(null, tmf.getTrustManagers(), null);
237
engine = ctxNoStaple.createSSLEngine();
238
engine.setUseClientMode(true);
239
engine.setEnabledProtocols(TLS13ONLY);
240
session = engine.getSession();
241
cTOs = ByteBuffer.allocateDirect(session.getPacketBufferSize());
242
243
// Create and check the ClientHello message
244
clientResult = engine.wrap(clientOut, cTOs);
245
log("client wrap: ", clientResult);
246
if (clientResult.getStatus() != SSLEngineResult.Status.OK) {
247
throw new SSLException("Client wrap got status: " +
248
clientResult.getStatus());
249
}
250
cTOs.flip();
251
System.out.println(dumpHexBytes(cTOs));
252
checkClientHello(cTOs, false, false);
253
cHello13NoStaple = cTOs;
254
255
// A TLS 1.3-capable hello, one that is not strictly limited to
256
// the TLS 1.3 protocol should have both status_request and
257
// status_request_v2
258
System.out.println("=========================================");
259
System.out.println("Client Test 5: " +
260
"jdk.tls.client.enableStatusRequestExtension = true");
261
System.out.println("Version = TLS 1.3 capable [default hello]");
262
System.out.println("=========================================");
263
264
System.setProperty("jdk.tls.client.enableStatusRequestExtension",
265
"true");
266
ctxStaple = SSLContext.getInstance("TLS");
267
ctxStaple.init(null, tmf.getTrustManagers(), null);
268
engine = ctxStaple.createSSLEngine();
269
engine.setUseClientMode(true);
270
// Note: Unlike the other tests, there is no explicit protocol setting
271
session = engine.getSession();
272
cTOs = ByteBuffer.allocateDirect(session.getPacketBufferSize());
273
274
// Create and check the ClientHello message
275
clientResult = engine.wrap(clientOut, cTOs);
276
log("client wrap: ", clientResult);
277
if (clientResult.getStatus() != SSLEngineResult.Status.OK) {
278
throw new SSLException("Client wrap got status: " +
279
clientResult.getStatus());
280
}
281
cTOs.flip();
282
System.out.println(dumpHexBytes(cTOs));
283
checkClientHello(cTOs, true, true);
284
}
285
286
private static void testServerProp() throws Exception {
287
SSLEngineResult serverResult;
288
HandshakeStatus hsStat;
289
290
// Test with the server-side enable property set to true
291
System.out.println("=========================================");
292
System.out.println("Server Test 1: " +
293
"jdk.tls.server.enableStatusRequestExtension = true");
294
System.out.println("Version = TLS 1.2");
295
System.out.println("=========================================");
296
297
System.setProperty("jdk.tls.server.enableStatusRequestExtension",
298
"true");
299
SSLContext ctxStaple = SSLContext.getInstance("TLS");
300
ctxStaple.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
301
SSLEngine engine = ctxStaple.createSSLEngine();
302
engine.setUseClientMode(false);
303
engine.setEnabledProtocols(TLS12MAX);
304
SSLSession session = engine.getSession();
305
ByteBuffer serverOut = ByteBuffer.wrap("I'm a Server".getBytes());
306
ByteBuffer serverIn =
307
ByteBuffer.allocate(session.getApplicationBufferSize() + 50);
308
ByteBuffer sTOc =
309
ByteBuffer.allocateDirect(session.getPacketBufferSize());
310
311
// Consume the client hello
312
serverResult = engine.unwrap(cHello12Staple, serverIn);
313
log("server unwrap: ", serverResult);
314
if (serverResult.getStatus() != SSLEngineResult.Status.OK) {
315
throw new SSLException("Server unwrap got status: " +
316
serverResult.getStatus());
317
} else if (serverResult.getHandshakeStatus() !=
318
SSLEngineResult.HandshakeStatus.NEED_TASK) {
319
throw new SSLException("Server unwrap expected NEED_TASK, got: " +
320
serverResult.getHandshakeStatus());
321
}
322
runDelegatedTasks(serverResult, engine);
323
if (engine.getHandshakeStatus() !=
324
SSLEngineResult.HandshakeStatus.NEED_WRAP) {
325
throw new SSLException("Expected NEED_WRAP, got: " +
326
engine.getHandshakeStatus());
327
}
328
329
// Generate a TLS record with the ServerHello
330
serverResult = engine.wrap(serverOut, sTOc);
331
log("client wrap: ", serverResult);
332
if (serverResult.getStatus() != SSLEngineResult.Status.OK) {
333
throw new SSLException("Client wrap got status: " +
334
serverResult.getStatus());
335
}
336
sTOc.flip();
337
System.out.println(dumpHexBytes(sTOc));
338
checkServerHello(sTOc, false, true);
339
340
// Flip the client hello so we can reuse it in the next test.
341
cHello12Staple.flip();
342
343
// Test with the server-side enable property set to false
344
System.out.println("=========================================");
345
System.out.println("Server Test 2: " +
346
"jdk.tls.server.enableStatusRequestExtension = false");
347
System.out.println("Version = TLS 1.2");
348
System.out.println("=========================================");
349
350
System.setProperty("jdk.tls.server.enableStatusRequestExtension",
351
"false");
352
SSLContext ctxNoStaple = SSLContext.getInstance("TLS");
353
ctxNoStaple.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
354
engine = ctxNoStaple.createSSLEngine();
355
engine.setUseClientMode(false);
356
engine.setEnabledProtocols(TLS12MAX);
357
session = engine.getSession();
358
serverIn = ByteBuffer.allocate(session.getApplicationBufferSize() + 50);
359
sTOc = ByteBuffer.allocateDirect(session.getPacketBufferSize());
360
361
// Consume the client hello
362
serverResult = engine.unwrap(cHello12Staple, serverIn);
363
log("server unwrap: ", serverResult);
364
if (serverResult.getStatus() != SSLEngineResult.Status.OK) {
365
throw new SSLException("Server unwrap got status: " +
366
serverResult.getStatus());
367
} else if (serverResult.getHandshakeStatus() !=
368
SSLEngineResult.HandshakeStatus.NEED_TASK) {
369
throw new SSLException("Server unwrap expected NEED_TASK, got: " +
370
serverResult.getHandshakeStatus());
371
}
372
runDelegatedTasks(serverResult, engine);
373
if (engine.getHandshakeStatus() !=
374
SSLEngineResult.HandshakeStatus.NEED_WRAP) {
375
throw new SSLException("Expected NEED_WRAP, got: " +
376
engine.getHandshakeStatus());
377
}
378
379
// Generate a TLS record with the ServerHello
380
serverResult = engine.wrap(serverOut, sTOc);
381
log("client wrap: ", serverResult);
382
if (serverResult.getStatus() != SSLEngineResult.Status.OK) {
383
throw new SSLException("Client wrap got status: " +
384
serverResult.getStatus());
385
}
386
sTOc.flip();
387
System.out.println(dumpHexBytes(sTOc));
388
checkServerHello(sTOc, false, false);
389
}
390
391
/*
392
* If the result indicates that we have outstanding tasks to do,
393
* go ahead and run them in this thread.
394
*/
395
private static void runDelegatedTasks(SSLEngineResult result,
396
SSLEngine engine) throws Exception {
397
398
if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
399
Runnable runnable;
400
while ((runnable = engine.getDelegatedTask()) != null) {
401
log("\trunning delegated task...");
402
runnable.run();
403
}
404
HandshakeStatus hsStatus = engine.getHandshakeStatus();
405
if (hsStatus == HandshakeStatus.NEED_TASK) {
406
throw new Exception(
407
"handshake shouldn't need additional tasks");
408
}
409
log("\tnew HandshakeStatus: " + hsStatus);
410
}
411
}
412
413
private static void log(String str, SSLEngineResult result) {
414
if (!logging) {
415
return;
416
}
417
HandshakeStatus hsStatus = result.getHandshakeStatus();
418
log(str +
419
result.getStatus() + "/" + hsStatus + ", " +
420
result.bytesConsumed() + "/" + result.bytesProduced() +
421
" bytes");
422
if (hsStatus == HandshakeStatus.FINISHED) {
423
log("\t...ready for application data");
424
}
425
}
426
427
private static void log(String str) {
428
if (logging) {
429
System.out.println(str);
430
}
431
}
432
433
/**
434
* Dump a ByteBuffer as a hexdump to stdout. The dumping routine will
435
* start at the current position of the buffer and run to its limit.
436
* After completing the dump, the position will be returned to its
437
* starting point.
438
*
439
* @param data the ByteBuffer to dump to stdout.
440
*
441
* @return the hexdump of the byte array.
442
*/
443
private static String dumpHexBytes(ByteBuffer data) {
444
StringBuilder sb = new StringBuilder();
445
if (data != null) {
446
int i = 0;
447
data.mark();
448
while (data.hasRemaining()) {
449
if (i % 16 == 0 && i != 0) {
450
sb.append("\n");
451
}
452
sb.append(String.format("%02X ", data.get()));
453
i++;
454
}
455
data.reset();
456
}
457
458
return sb.toString();
459
}
460
461
/**
462
* Tests the ClientHello for the presence (or not) of the status_request
463
* and status_request_v2 hello extensions. It is assumed that the provided
464
* ByteBuffer has its position set at the first byte of the TLS record
465
* containing the ClientHello and contains the entire hello message. Upon
466
* successful completion of this method the ByteBuffer will have its
467
* position reset to the initial offset in the buffer. If an exception is
468
* thrown the position at the time of the exception will be preserved.
469
*
470
* @param data the ByteBuffer containing the ClientHello bytes
471
* @param statReqPresent true if the status_request hello extension should
472
* be present.
473
* @param statReqV2Present true if the status_request_v2 hello extension
474
* should be present.
475
*
476
* @throws SSLException if the presence or lack of either the
477
* status_request or status_request_v2 extensions is inconsistent with
478
* the expected settings in the statReqPresent or statReqV2Present
479
* parameters.
480
*/
481
private static void checkClientHello(ByteBuffer data,
482
boolean statReqPresent, boolean statReqV2Present)
483
throws SSLException {
484
boolean hasV1 = false;
485
boolean hasV2 = false;
486
Objects.requireNonNull(data);
487
data.mark();
488
489
// Process the TLS record header
490
int type = Byte.toUnsignedInt(data.get());
491
int ver_major = Byte.toUnsignedInt(data.get());
492
int ver_minor = Byte.toUnsignedInt(data.get());
493
int recLen = Short.toUnsignedInt(data.getShort());
494
495
// Simple sanity checks
496
if (type != 22) {
497
throw new SSLException("Not a handshake: Type = " + type);
498
} else if (recLen > data.remaining()) {
499
throw new SSLException("Incomplete record in buffer: " +
500
"Record length = " + recLen + ", Remaining = " +
501
data.remaining());
502
}
503
504
// Grab the handshake message header.
505
int msgHdr = data.getInt();
506
int msgType = (msgHdr >> 24) & 0x000000FF;
507
int msgLen = msgHdr & 0x00FFFFFF;
508
509
// More simple sanity checks
510
if (msgType != 1) {
511
throw new SSLException("Not a ClientHello: Type = " + msgType);
512
}
513
514
// Skip over the protocol version and client random
515
data.position(data.position() + 34);
516
517
// Jump past the session ID (if there is one)
518
int sessLen = Byte.toUnsignedInt(data.get());
519
if (sessLen != 0) {
520
data.position(data.position() + sessLen);
521
}
522
523
// Jump past the cipher suites
524
int csLen = Short.toUnsignedInt(data.getShort());
525
if (csLen != 0) {
526
data.position(data.position() + csLen);
527
}
528
529
// ...and the compression
530
int compLen = Byte.toUnsignedInt(data.get());
531
if (compLen != 0) {
532
data.position(data.position() + compLen);
533
}
534
535
// Now for the fun part. Go through the extensions and look
536
// for the two status request exts.
537
int extsLen = Short.toUnsignedInt(data.getShort());
538
while (data.hasRemaining()) {
539
int extType = Short.toUnsignedInt(data.getShort());
540
int extLen = Short.toUnsignedInt(data.getShort());
541
hasV1 |= (extType == HELLO_EXT_STATUS_REQ);
542
hasV2 |= (extType == HELLO_EXT_STATUS_REQ_V2);
543
data.position(data.position() + extLen);
544
}
545
546
if (hasV1 != statReqPresent) {
547
throw new SSLException("The status_request extension is " +
548
"inconsistent with the expected result: expected = " +
549
statReqPresent + ", actual = " + hasV1);
550
} else if (hasV2 != statReqV2Present) {
551
throw new SSLException("The status_request_v2 extension is " +
552
"inconsistent with the expected result: expected = " +
553
statReqV2Present + ", actual = " + hasV2);
554
}
555
556
// We should be at the end of the ClientHello
557
data.reset();
558
}
559
560
/**
561
* Tests the ServerHello for the presence (or not) of the status_request
562
* or status_request_v2 hello extension. It is assumed that the provided
563
* ByteBuffer has its position set at the first byte of the TLS record
564
* containing the ServerHello and contains the entire hello message. Upon
565
* successful completion of this method the ByteBuffer will have its
566
* position reset to the initial offset in the buffer. If an exception is
567
* thrown the position at the time of the exception will be preserved.
568
*
569
* @param statReqPresent true if the status_request hello extension should
570
* be present.
571
* @param statReqV2Present true if the status_request_v2 hello extension
572
* should be present.
573
*
574
* @throws SSLException if the presence or lack of either the
575
* status_request or status_request_v2 extensions is inconsistent with
576
* the expected settings in the statReqPresent or statReqV2Present
577
* parameters.
578
*/
579
private static void checkServerHello(ByteBuffer data,
580
boolean statReqPresent, boolean statReqV2Present)
581
throws SSLException {
582
boolean hasV1 = false;
583
boolean hasV2 = false;
584
Objects.requireNonNull(data);
585
int startPos = data.position();
586
data.mark();
587
588
// Process the TLS record header
589
int type = Byte.toUnsignedInt(data.get());
590
int ver_major = Byte.toUnsignedInt(data.get());
591
int ver_minor = Byte.toUnsignedInt(data.get());
592
int recLen = Short.toUnsignedInt(data.getShort());
593
594
// Simple sanity checks
595
if (type != 22) {
596
throw new SSLException("Not a handshake: Type = " + type);
597
} else if (recLen > data.remaining()) {
598
throw new SSLException("Incomplete record in buffer: " +
599
"Record length = " + recLen + ", Remaining = " +
600
data.remaining());
601
}
602
603
// Grab the handshake message header.
604
int msgHdr = data.getInt();
605
int msgType = (msgHdr >> 24) & 0x000000FF;
606
int msgLen = msgHdr & 0x00FFFFFF;
607
608
// More simple sanity checks
609
if (msgType != 2) {
610
throw new SSLException("Not a ServerHello: Type = " + msgType);
611
}
612
613
// Skip over the protocol version and server random
614
data.position(data.position() + 34);
615
616
// Jump past the session ID
617
int sessLen = Byte.toUnsignedInt(data.get());
618
if (sessLen != 0) {
619
data.position(data.position() + sessLen);
620
}
621
622
// Skip the cipher suite and compression method
623
data.position(data.position() + 3);
624
625
// Go through the extensions and look for the request extension
626
// expected by the caller.
627
int extsLen = Short.toUnsignedInt(data.getShort());
628
while (data.position() < recLen + startPos + 5) {
629
int extType = Short.toUnsignedInt(data.getShort());
630
int extLen = Short.toUnsignedInt(data.getShort());
631
hasV1 |= (extType == HELLO_EXT_STATUS_REQ);
632
hasV2 |= (extType == HELLO_EXT_STATUS_REQ_V2);
633
data.position(data.position() + extLen);
634
}
635
636
if (hasV1 != statReqPresent) {
637
throw new SSLException("The status_request extension is " +
638
"inconsistent with the expected result: expected = " +
639
statReqPresent + ", actual = " + hasV1);
640
} else if (hasV2 != statReqV2Present) {
641
throw new SSLException("The status_request_v2 extension is " +
642
"inconsistent with the expected result: expected = " +
643
statReqV2Present + ", actual = " + hasV2);
644
}
645
646
// Reset the position to the initial spot at the start of this method.
647
data.reset();
648
}
649
650
/**
651
* Creates the PKI components necessary for this test, including
652
* Root CA, Intermediate CA and SSL server certificates, the keystores
653
* for each entity, a client trust store, and starts the OCSP responders.
654
*/
655
private static void createPKI() throws Exception {
656
CertificateBuilder cbld = new CertificateBuilder();
657
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
658
keyGen.initialize(2048);
659
KeyStore.Builder keyStoreBuilder =
660
KeyStore.Builder.newInstance("PKCS12", null,
661
new KeyStore.PasswordProtection(passwd.toCharArray()));
662
663
// Generate Root, IntCA, EE keys
664
KeyPair rootCaKP = keyGen.genKeyPair();
665
log("Generated Root CA KeyPair");
666
KeyPair intCaKP = keyGen.genKeyPair();
667
log("Generated Intermediate CA KeyPair");
668
KeyPair sslKP = keyGen.genKeyPair();
669
log("Generated SSL Cert KeyPair");
670
671
// Set up the Root CA Cert
672
cbld.setSubjectName("CN=Root CA Cert, O=SomeCompany");
673
cbld.setPublicKey(rootCaKP.getPublic());
674
cbld.setSerialNumber(new BigInteger("1"));
675
// Make a 3 year validity starting from 60 days ago
676
long start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(60);
677
long end = start + TimeUnit.DAYS.toMillis(1085);
678
cbld.setValidity(new Date(start), new Date(end));
679
addCommonExts(cbld, rootCaKP.getPublic(), rootCaKP.getPublic());
680
addCommonCAExts(cbld);
681
// Make our Root CA Cert!
682
X509Certificate rootCert = cbld.build(null, rootCaKP.getPrivate(),
683
"SHA256withRSA");
684
log("Root CA Created:\n" + certInfo(rootCert));
685
686
// Now build a keystore and add the keys and cert
687
rootKeystore = keyStoreBuilder.getKeyStore();
688
java.security.cert.Certificate[] rootChain = {rootCert};
689
rootKeystore.setKeyEntry(ROOT_ALIAS, rootCaKP.getPrivate(),
690
passwd.toCharArray(), rootChain);
691
692
// Now fire up the OCSP responder
693
rootOcsp = new SimpleOCSPServer(rootKeystore, passwd, ROOT_ALIAS, null);
694
rootOcsp.enableLog(logging);
695
rootOcsp.setNextUpdateInterval(3600);
696
rootOcsp.start();
697
698
// Wait 5 seconds for server ready
699
for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) {
700
Thread.sleep(50);
701
}
702
if (!rootOcsp.isServerReady()) {
703
throw new RuntimeException("Server not ready yet");
704
}
705
706
rootOcspPort = rootOcsp.getPort();
707
String rootRespURI = "http://localhost:" + rootOcspPort;
708
log("Root OCSP Responder URI is " + rootRespURI);
709
710
// Now that we have the root keystore and OCSP responder we can
711
// create our intermediate CA.
712
cbld.reset();
713
cbld.setSubjectName("CN=Intermediate CA Cert, O=SomeCompany");
714
cbld.setPublicKey(intCaKP.getPublic());
715
cbld.setSerialNumber(new BigInteger("100"));
716
// Make a 2 year validity starting from 30 days ago
717
start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(30);
718
end = start + TimeUnit.DAYS.toMillis(730);
719
cbld.setValidity(new Date(start), new Date(end));
720
addCommonExts(cbld, intCaKP.getPublic(), rootCaKP.getPublic());
721
addCommonCAExts(cbld);
722
cbld.addAIAExt(Collections.singletonList(rootRespURI));
723
// Make our Intermediate CA Cert!
724
X509Certificate intCaCert = cbld.build(rootCert, rootCaKP.getPrivate(),
725
"SHA256withRSA");
726
log("Intermediate CA Created:\n" + certInfo(intCaCert));
727
728
// Provide intermediate CA cert revocation info to the Root CA
729
// OCSP responder.
730
Map<BigInteger, SimpleOCSPServer.CertStatusInfo> revInfo =
731
new HashMap<>();
732
revInfo.put(intCaCert.getSerialNumber(),
733
new SimpleOCSPServer.CertStatusInfo(
734
SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD));
735
rootOcsp.updateStatusDb(revInfo);
736
737
// Now build a keystore and add the keys, chain and root cert as a TA
738
intKeystore = keyStoreBuilder.getKeyStore();
739
java.security.cert.Certificate[] intChain = {intCaCert, rootCert};
740
intKeystore.setKeyEntry(INT_ALIAS, intCaKP.getPrivate(),
741
passwd.toCharArray(), intChain);
742
intKeystore.setCertificateEntry(ROOT_ALIAS, rootCert);
743
744
// Now fire up the Intermediate CA OCSP responder
745
intOcsp = new SimpleOCSPServer(intKeystore, passwd,
746
INT_ALIAS, null);
747
intOcsp.enableLog(logging);
748
intOcsp.setNextUpdateInterval(3600);
749
intOcsp.start();
750
751
// Wait 5 seconds for server ready
752
for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) {
753
Thread.sleep(50);
754
}
755
if (!intOcsp.isServerReady()) {
756
throw new RuntimeException("Server not ready yet");
757
}
758
759
intOcspPort = intOcsp.getPort();
760
String intCaRespURI = "http://localhost:" + intOcspPort;
761
log("Intermediate CA OCSP Responder URI is " + intCaRespURI);
762
763
// Last but not least, let's make our SSLCert and add it to its own
764
// Keystore
765
cbld.reset();
766
cbld.setSubjectName("CN=SSLCertificate, O=SomeCompany");
767
cbld.setPublicKey(sslKP.getPublic());
768
cbld.setSerialNumber(new BigInteger("4096"));
769
// Make a 1 year validity starting from 7 days ago
770
start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7);
771
end = start + TimeUnit.DAYS.toMillis(365);
772
cbld.setValidity(new Date(start), new Date(end));
773
774
// Add extensions
775
addCommonExts(cbld, sslKP.getPublic(), intCaKP.getPublic());
776
boolean[] kuBits = {true, false, true, false, false, false,
777
false, false, false};
778
cbld.addKeyUsageExt(kuBits);
779
List<String> ekuOids = new ArrayList<>();
780
ekuOids.add("1.3.6.1.5.5.7.3.1");
781
ekuOids.add("1.3.6.1.5.5.7.3.2");
782
cbld.addExtendedKeyUsageExt(ekuOids);
783
cbld.addSubjectAltNameDNSExt(Collections.singletonList("localhost"));
784
cbld.addAIAExt(Collections.singletonList(intCaRespURI));
785
// Make our SSL Server Cert!
786
X509Certificate sslCert = cbld.build(intCaCert, intCaKP.getPrivate(),
787
"SHA256withRSA");
788
log("SSL Certificate Created:\n" + certInfo(sslCert));
789
790
// Provide SSL server cert revocation info to the Intermeidate CA
791
// OCSP responder.
792
revInfo = new HashMap<>();
793
revInfo.put(sslCert.getSerialNumber(),
794
new SimpleOCSPServer.CertStatusInfo(
795
SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD));
796
intOcsp.updateStatusDb(revInfo);
797
798
// Now build a keystore and add the keys, chain and root cert as a TA
799
serverKeystore = keyStoreBuilder.getKeyStore();
800
java.security.cert.Certificate[] sslChain = {sslCert, intCaCert, rootCert};
801
serverKeystore.setKeyEntry(SSL_ALIAS, sslKP.getPrivate(),
802
passwd.toCharArray(), sslChain);
803
serverKeystore.setCertificateEntry(ROOT_ALIAS, rootCert);
804
805
// And finally a Trust Store for the client
806
trustStore = keyStoreBuilder.getKeyStore();
807
trustStore.setCertificateEntry(ROOT_ALIAS, rootCert);
808
}
809
810
private static void addCommonExts(CertificateBuilder cbld,
811
PublicKey subjKey, PublicKey authKey) throws IOException {
812
cbld.addSubjectKeyIdExt(subjKey);
813
cbld.addAuthorityKeyIdExt(authKey);
814
}
815
816
private static void addCommonCAExts(CertificateBuilder cbld)
817
throws IOException {
818
cbld.addBasicConstraintsExt(true, true, -1);
819
// Set key usage bits for digitalSignature, keyCertSign and cRLSign
820
boolean[] kuBitSettings = {true, false, false, false, false, true,
821
true, false, false};
822
cbld.addKeyUsageExt(kuBitSettings);
823
}
824
825
/**
826
* Helper routine that dumps only a few cert fields rather than
827
* the whole toString() output.
828
*
829
* @param cert an X509Certificate to be displayed
830
*
831
* @return the String output of the issuer, subject and
832
* serial number
833
*/
834
private static String certInfo(X509Certificate cert) {
835
StringBuilder sb = new StringBuilder();
836
sb.append("Issuer: ").append(cert.getIssuerX500Principal()).
837
append("\n");
838
sb.append("Subject: ").append(cert.getSubjectX500Principal()).
839
append("\n");
840
sb.append("Serial: ").append(cert.getSerialNumber()).append("\n");
841
return sb.toString();
842
}
843
}
844
845