Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/net/ssl/compatibility/ClientHelloProcessing.java
41152 views
1
/*
2
* Copyright (c) 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
/*
25
* @test
26
* @bug 8210918 8210334 8209916
27
* @summary Add test to exercise server-side client hello processing
28
* @run main/othervm ClientHelloProcessing noPskNoKexModes
29
* @run main/othervm ClientHelloProcessing noPskYesKexModes
30
* @run main/othervm ClientHelloProcessing yesPskNoKexModes
31
* @run main/othervm ClientHelloProcessing yesPskYesKexModes
32
* @run main/othervm ClientHelloProcessing supGroupsSect163k1
33
*/
34
35
/*
36
* SunJSSE does not support dynamic system properties, no way to re-use
37
* system properties in samevm/agentvm mode.
38
*/
39
40
import java.io.FileInputStream;
41
import javax.net.ssl.*;
42
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
43
import java.io.IOException;
44
import java.nio.ByteBuffer;
45
import java.security.GeneralSecurityException;
46
import java.security.KeyStore;
47
import java.util.Map;
48
import java.util.HashMap;
49
import java.util.Objects;
50
51
/*
52
* If you wish to add test cases, the following must be done:
53
* 1. Add a @run line with the parameter being a name for the test case
54
* 2. Create the ClientHello as a byte[]. It should be a complete TLS
55
* record, but does not need upper layer headers like TCP, IP, Ethernet, etc.
56
* 3. Create a new TestCase instance, see "noPskNoKexModes" as an example
57
* 4. Create a mapping between the test case name in your @run line and the
58
* TestCase object you created in step #3. Add this to TESTMAP.
59
*/
60
61
public class ClientHelloProcessing {
62
63
private static final ByteBuffer SERVOUTBUF =
64
ByteBuffer.wrap("Server Side".getBytes());
65
66
private static final String pathToStores = "../etc";
67
private static final String keyStoreFile = "keystore";
68
private static final String trustStoreFile = "truststore";
69
private static final String passwd = "passphrase";
70
71
private static final String keyFilename =
72
System.getProperty("test.src", ".") + "/" + pathToStores +
73
"/" + keyStoreFile;
74
private static final String trustFilename =
75
System.getProperty("test.src", ".") + "/" + pathToStores +
76
"/" + trustStoreFile;
77
78
private static TrustManagerFactory trustMgrFac = null;
79
private static KeyManagerFactory keyMgrFac = null;
80
81
// Canned client hello messages
82
// These were created from packet captures using openssl 1.1.1's
83
// s_client utility. The captured TLS record containing the client
84
// hello was then manually edited to remove or add fields if the s_client
85
// utility could not be used to generate a message with the desired
86
// extensions. When manually altering the hello messages, care must
87
// be taken to change the lengths of the extensions themselves, the
88
// extensions vector length, the handshake message length, and the TLS
89
// record length.
90
91
// Client Hello with the pre_shared_key and psk_key_exchange_modes
92
// both absent. Required manual removal of the psk_key_exchange_modes
93
// extension. Similarly formed Client Hello messages may be generated
94
// by clients that don't support pre-shared keys.
95
//
96
// TLSv1.3 Record Layer: Handshake Protocol: Client Hello
97
// Content Type: Handshake (22)
98
// Version: TLS 1.0 (0x0301)
99
// Length: 256
100
// Handshake Protocol: Client Hello
101
// Handshake Type: Client Hello (1)
102
// Length: 252
103
// Version: TLS 1.2 (0x0303)
104
// Random: 9b796ad0cbd559fb48fc4ba32da5bb8c1ef9a7da85231860...
105
// Session ID Length: 32
106
// Session ID: fe8411205bc99a506952f5c28569facb96ff0f37621be072...
107
// Cipher Suites Length: 8
108
// Cipher Suites (4 suites)
109
// Compression Methods Length: 1
110
// Compression Methods (1 method)
111
// Extensions Length: 171
112
// Extension: server_name (len=14)
113
// Extension: ec_point_formats (len=4)
114
// Extension: supported_groups (len=4)
115
// Extension: SessionTicket TLS (len=0)
116
// Extension: status_request (len=5)
117
// Extension: encrypt_then_mac (len=0)
118
// Extension: extended_master_secret (len=0)
119
// Extension: signature_algorithms (len=30)
120
// Extension: supported_versions (len=3)
121
// Extension: key_share (len=71)
122
private static final byte[] CLIHELLO_NOPSK_NOPSKEXMODE = {
123
22, 3, 1, 1, 0, 1, 0, 0,
124
-4, 3, 3, -101, 121, 106, -48, -53,
125
-43, 89, -5, 72, -4, 75, -93, 45,
126
-91, -69, -116, 30, -7, -89, -38, -123,
127
35, 24, 96, 29, -93, -22, 10, -97,
128
-15, -11, 3, 32, -2, -124, 17, 32,
129
91, -55, -102, 80, 105, 82, -11, -62,
130
-123, 105, -6, -53, -106, -1, 15, 55,
131
98, 27, -32, 114, -126, -13, 42, -104,
132
-102, 37, -65, 52, 0, 8, 19, 2,
133
19, 3, 19, 1, 0, -1, 1, 0,
134
0, -85, 0, 0, 0, 14, 0, 12,
135
0, 0, 9, 108, 111, 99, 97, 108,
136
104, 111, 115, 116, 0, 11, 0, 4,
137
3, 0, 1, 2, 0, 10, 0, 4,
138
0, 2, 0, 23, 0, 35, 0, 0,
139
0, 5, 0, 5, 1, 0, 0, 0,
140
0, 0, 22, 0, 0, 0, 23, 0,
141
0, 0, 13, 0, 30, 0, 28, 4,
142
3, 5, 3, 6, 3, 8, 7, 8,
143
8, 8, 9, 8, 10, 8, 11, 8,
144
4, 8, 5, 8, 6, 4, 1, 5,
145
1, 6, 1, 0, 43, 0, 3, 2,
146
3, 4, 0, 51, 0, 71, 0, 69,
147
0, 23, 0, 65, 4, 125, -92, -50,
148
-91, -39, -55, -114, 0, 22, 2, -50,
149
123, -126, 0, -94, 100, -119, -106, 125,
150
-81, -24, 51, -84, 25, 25, -115, 13,
151
-17, -20, 93, 68, -97, -79, -98, 91,
152
86, 91, -114, 123, 119, -87, -12, 32,
153
63, -41, 50, 126, -70, 96, 33, -6,
154
94, -7, -68, 54, -47, 53, 0, 88,
155
40, -48, -102, -50, 88
156
};
157
158
// Client Hello with the pre_shared_key extension absent but
159
// containing the psk_key_exchange_modes extension asserted. No
160
// manual modification was necessary.
161
//
162
// TLSv1.3 Record Layer: Handshake Protocol: Client Hello
163
// Content Type: Handshake (22)
164
// Version: TLS 1.0 (0x0301)
165
// Length: 262
166
// Handshake Protocol: Client Hello
167
// Handshake Type: Client Hello (1)
168
// Length: 258
169
// Version: TLS 1.2 (0x0303)
170
// Random: 9b796ad0cbd559fb48fc4ba32da5bb8c1ef9a7da85231860...
171
// Session ID Length: 32
172
// Session ID: fe8411205bc99a506952f5c28569facb96ff0f37621be072...
173
// Cipher Suites Length: 8
174
// Cipher Suites (4 suites)
175
// Compression Methods Length: 1
176
// Compression Methods (1 method)
177
// Extensions Length: 177
178
// Extension: server_name (len=14)
179
// Extension: ec_point_formats (len=4)
180
// Extension: supported_groups (len=4)
181
// Extension: SessionTicket TLS (len=0)
182
// Extension: status_request (len=5)
183
// Extension: encrypt_then_mac (len=0)
184
// Extension: extended_master_secret (len=0)
185
// Extension: signature_algorithms (len=30)
186
// Extension: supported_versions (len=3)
187
// Extension: psk_key_exchange_modes (len=2)
188
// Type: psk_key_exchange_modes (45)
189
// Length: 2
190
// PSK Key Exchange Modes Length: 1
191
// PSK Key Exchange Mode: PSK with (EC)DHE key establishment (psk_dhe_ke) (1)
192
// Extension: key_share (len=71)
193
private static final byte[] CLIHELLO_NOPSK_YESPSKEXMODE = {
194
22, 3, 1, 1, 6, 1, 0, 1,
195
2, 3, 3, -101, 121, 106, -48, -53,
196
-43, 89, -5, 72, -4, 75, -93, 45,
197
-91, -69, -116, 30, -7, -89, -38, -123,
198
35, 24, 96, 29, -93, -22, 10, -97,
199
-15, -11, 3, 32, -2, -124, 17, 32,
200
91, -55, -102, 80, 105, 82, -11, -62,
201
-123, 105, -6, -53, -106, -1, 15, 55,
202
98, 27, -32, 114, -126, -13, 42, -104,
203
-102, 37, -65, 52, 0, 8, 19, 2,
204
19, 3, 19, 1, 0, -1, 1, 0,
205
0, -79, 0, 0, 0, 14, 0, 12,
206
0, 0, 9, 108, 111, 99, 97, 108,
207
104, 111, 115, 116, 0, 11, 0, 4,
208
3, 0, 1, 2, 0, 10, 0, 4,
209
0, 2, 0, 23, 0, 35, 0, 0,
210
0, 5, 0, 5, 1, 0, 0, 0,
211
0, 0, 22, 0, 0, 0, 23, 0,
212
0, 0, 13, 0, 30, 0, 28, 4,
213
3, 5, 3, 6, 3, 8, 7, 8,
214
8, 8, 9, 8, 10, 8, 11, 8,
215
4, 8, 5, 8, 6, 4, 1, 5,
216
1, 6, 1, 0, 43, 0, 3, 2,
217
3, 4, 0, 45, 0, 2, 1, 1,
218
0, 51, 0, 71, 0, 69, 0, 23,
219
0, 65, 4, 125, -92, -50, -91, -39,
220
-55, -114, 0, 22, 2, -50, 123, -126,
221
0, -94, 100, -119, -106, 125, -81, -24,
222
51, -84, 25, 25, -115, 13, -17, -20,
223
93, 68, -97, -79, -98, 91, 86, 91,
224
-114, 123, 119, -87, -12, 32, 63, -41,
225
50, 126, -70, 96, 33, -6, 94, -7,
226
-68, 54, -47, 53, 0, 88, 40, -48,
227
-102, -50, 88
228
};
229
230
// Client Hello with pre_shared_key asserted and psk_key_exchange_modes
231
// absent. This is a violation of RFC 8446. This required manual
232
// removal of the psk_key_exchange_modes extension.
233
//
234
// TLSv1.3 Record Layer: Handshake Protocol: Client Hello
235
// Content Type: Handshake (22)
236
// Version: TLS 1.0 (0x0301)
237
// Length: 318
238
// Handshake Protocol: Client Hello
239
// Handshake Type: Client Hello (1)
240
// Length: 314
241
// Version: TLS 1.2 (0x0303)
242
// Random: e730e42336a19ed9fdb42919c65769132e9e779a797f188c...
243
// Session ID Length: 32
244
// Session ID: 6c6ed31408042fabd0c47fdeee6d19de2d6795e37590f00e...
245
// Cipher Suites Length: 8
246
// Cipher Suites (4 suites)
247
// Compression Methods Length: 1
248
// Compression Methods (1 method)
249
// Extensions Length: 233
250
// Extension: server_name (len=14)
251
// Extension: ec_point_formats (len=4)
252
// Extension: supported_groups (len=4)
253
// Extension: SessionTicket TLS (len=0)
254
// Extension: status_request (len=5)
255
// Extension: encrypt_then_mac (len=0)
256
// Extension: extended_master_secret (len=0)
257
// Extension: signature_algorithms (len=30)
258
// Extension: supported_versions (len=3)
259
// Extension: key_share (len=71)
260
// Extension: pre_shared_key (len=58)
261
// Type: pre_shared_key (41)
262
// Length: 58
263
// Pre-Shared Key extension
264
// Identities Length: 21
265
// PSK Identity (length: 15)
266
// Identity Length: 15
267
// Identity: 436c69656e745f6964656e74697479
268
// Obfuscated Ticket Age: 0
269
// PSK Binders length: 33
270
// PSK Binders
271
private static final byte[] CLIHELLO_YESPSK_NOPSKEXMODE = {
272
22, 3, 1, 1, 62, 1, 0, 1,
273
58, 3, 3, -25, 48, -28, 35, 54,
274
-95, -98, -39, -3, -76, 41, 25, -58,
275
87, 105, 19, 46, -98, 119, -102, 121,
276
127, 24, -116, -9, -99, 22, 116, -97,
277
90, 73, -18, 32, 108, 110, -45, 20,
278
8, 4, 47, -85, -48, -60, 127, -34,
279
-18, 109, 25, -34, 45, 103, -107, -29,
280
117, -112, -16, 14, -5, -24, 24, 61,
281
-9, 28, -119, -73, 0, 8, 19, 2,
282
19, 3, 19, 1, 0, -1, 1, 0,
283
0, -23, 0, 0, 0, 14, 0, 12,
284
0, 0, 9, 108, 111, 99, 97, 108,
285
104, 111, 115, 116, 0, 11, 0, 4,
286
3, 0, 1, 2, 0, 10, 0, 4,
287
0, 2, 0, 23, 0, 35, 0, 0,
288
0, 5, 0, 5, 1, 0, 0, 0,
289
0, 0, 22, 0, 0, 0, 23, 0,
290
0, 0, 13, 0, 30, 0, 28, 4,
291
3, 5, 3, 6, 3, 8, 7, 8,
292
8, 8, 9, 8, 10, 8, 11, 8,
293
4, 8, 5, 8, 6, 4, 1, 5,
294
1, 6, 1, 0, 43, 0, 3, 2,
295
3, 4, 0, 51, 0, 71, 0, 69,
296
0, 23, 0, 65, 4, -6, 101, 105,
297
-2, -6, 85, -99, -37, 112, 90, 44,
298
-123, -107, 4, -12, -64, 92, 40, 100,
299
22, -53, -124, 54, 56, 102, 25, 76,
300
-86, -1, 6, 110, 95, 92, -86, -35,
301
-101, 115, 85, 99, 19, 6, -43, 105,
302
-37, -92, 53, -97, 84, -1, -53, 87,
303
-53, -107, -13, -14, 32, 101, -35, 39,
304
102, -17, -119, -25, -51, 0, 41, 0,
305
58, 0, 21, 0, 15, 67, 108, 105,
306
101, 110, 116, 95, 105, 100, 101, 110,
307
116, 105, 116, 121, 0, 0, 0, 0,
308
0, 33, 32, -113, -27, -44, -71, -68,
309
-26, -47, 57, -82, -29, -13, -61, 77,
310
52, -60, 27, 74, -120, -104, 102, 21,
311
121, 0, 48, 43, -40, -19, -67, 57,
312
-20, 97, 23
313
};
314
315
// Client Hello containing both pre_shared_key and psk_key_exchange_modes
316
// extensions. Generation of this hello was done by adding
317
// "-psk a1b2c3d4" to the s_client command.
318
//
319
// TLSv1.3 Record Layer: Handshake Protocol: Client Hello
320
// Content Type: Handshake (22)
321
// Version: TLS 1.0 (0x0301)
322
// Length: 324
323
// Handshake Protocol: Client Hello
324
// Handshake Type: Client Hello (1)
325
// Length: 320
326
// Version: TLS 1.2 (0x0303)
327
// Random: e730e42336a19ed9fdb42919c65769132e9e779a797f188c...
328
// Session ID Length: 32
329
// Session ID: 6c6ed31408042fabd0c47fdeee6d19de2d6795e37590f00e...
330
// Cipher Suites Length: 8
331
// Cipher Suites (4 suites)
332
// Compression Methods Length: 1
333
// Compression Methods (1 method)
334
// Extensions Length: 239
335
// Extension: server_name (len=14)
336
// Extension: ec_point_formats (len=4)
337
// Extension: supported_groups (len=4)
338
// Extension: SessionTicket TLS (len=0)
339
// Extension: status_request (len=5)
340
// Extension: encrypt_then_mac (len=0)
341
// Extension: extended_master_secret (len=0)
342
// Extension: signature_algorithms (len=30)
343
// Extension: supported_versions (len=3)
344
// Extension: psk_key_exchange_modes (len=2)
345
// Type: psk_key_exchange_modes (45)
346
// Length: 2
347
// PSK Key Exchange Modes Length: 1
348
// PSK Key Exchange Mode: PSK with (EC)DHE key establishment (psk_dhe_ke) (1)
349
// Extension: key_share (len=71)
350
// Extension: pre_shared_key (len=58)
351
// Type: pre_shared_key (41)
352
// Length: 58
353
// Pre-Shared Key extension
354
// Identities Length: 21
355
// PSK Identity (length: 15)
356
// Identity Length: 15
357
// Identity: 436c69656e745f6964656e74697479
358
// Obfuscated Ticket Age: 0
359
// PSK Binders length: 33
360
// PSK Binders
361
private static final byte[] CLIHELLO_YESPSK_YESPSKEXMODE = {
362
22, 3, 1, 1, 68, 1, 0, 1,
363
64, 3, 3, -25, 48, -28, 35, 54,
364
-95, -98, -39, -3, -76, 41, 25, -58,
365
87, 105, 19, 46, -98, 119, -102, 121,
366
127, 24, -116, -9, -99, 22, 116, -97,
367
90, 73, -18, 32, 108, 110, -45, 20,
368
8, 4, 47, -85, -48, -60, 127, -34,
369
-18, 109, 25, -34, 45, 103, -107, -29,
370
117, -112, -16, 14, -5, -24, 24, 61,
371
-9, 28, -119, -73, 0, 8, 19, 2,
372
19, 3, 19, 1, 0, -1, 1, 0,
373
0, -17, 0, 0, 0, 14, 0, 12,
374
0, 0, 9, 108, 111, 99, 97, 108,
375
104, 111, 115, 116, 0, 11, 0, 4,
376
3, 0, 1, 2, 0, 10, 0, 4,
377
0, 2, 0, 23, 0, 35, 0, 0,
378
0, 5, 0, 5, 1, 0, 0, 0,
379
0, 0, 22, 0, 0, 0, 23, 0,
380
0, 0, 13, 0, 30, 0, 28, 4,
381
3, 5, 3, 6, 3, 8, 7, 8,
382
8, 8, 9, 8, 10, 8, 11, 8,
383
4, 8, 5, 8, 6, 4, 1, 5,
384
1, 6, 1, 0, 43, 0, 3, 2,
385
3, 4, 0, 45, 0, 2, 1, 1,
386
0, 51, 0, 71, 0, 69, 0, 23,
387
0, 65, 4, -6, 101, 105, -2, -6,
388
85, -99, -37, 112, 90, 44, -123, -107,
389
4, -12, -64, 92, 40, 100, 22, -53,
390
-124, 54, 56, 102, 25, 76, -86, -1,
391
6, 110, 95, 92, -86, -35, -101, 115,
392
85, 99, 19, 6, -43, 105, -37, -92,
393
53, -97, 84, -1, -53, 87, -53, -107,
394
-13, -14, 32, 101, -35, 39, 102, -17,
395
-119, -25, -51, 0, 41, 0, 58, 0,
396
21, 0, 15, 67, 108, 105, 101, 110,
397
116, 95, 105, 100, 101, 110, 116, 105,
398
116, 121, 0, 0, 0, 0, 0, 33,
399
32, -113, -27, -44, -71, -68, -26, -47,
400
57, -82, -29, -13, -61, 77, 52, -60,
401
27, 74, -120, -104, 102, 21, 121, 0,
402
48, 43, -40, -19, -67, 57, -20, 97,
403
23
404
};
405
406
// Client Hello with sect163k1 and secp256r1 as supported groups. This
407
// test covers an error condition where a known, supported curve that is
408
// not in the default enabled set of curves would cause failures.
409
// Generation of this hello was done using "-curves sect163k1:prime256v1"
410
// as an option to s_client.
411
//
412
// TLSv1.2 Record Layer: Handshake Protocol: Client Hello
413
// Content Type: Handshake (22)
414
// Version: TLS 1.0 (0x0301)
415
// Length: 210
416
// Handshake Protocol: Client Hello
417
// Handshake Type: Client Hello (1)
418
// Length: 206
419
// Version: TLS 1.2 (0x0303)
420
// Random: 05cbae9b834851d856355b72601cb67b7cd4eb51f29ed50b...
421
// Session ID Length: 0
422
// Cipher Suites Length: 56
423
// Cipher Suites (28 suites)
424
// Compression Methods Length: 1
425
// Compression Methods (1 method)
426
// Extensions Length: 109
427
// Extension: server_name (len=14)
428
// Extension: ec_point_formats (len=4)
429
// Extension: supported_groups (len=6)
430
// Type: supported_groups (10)
431
// Length: 6
432
// Supported Groups List Length: 4
433
// Supported Groups (2 groups)
434
// Supported Group: sect163k1 (0x0001)
435
// Supported Group: secp256r1 (0x0017)
436
// Extension: SessionTicket TLS (len=0)
437
// Extension: status_request (len=5)
438
// Extension: encrypt_then_mac (len=0)
439
// Extension: extended_master_secret (len=0)
440
// Extension: signature_algorithms (len=48)
441
private static final byte[] CLIHELLO_SUPGRP_SECT163K1 = {
442
22, 3, 1, 0, -46, 1, 0, 0,
443
-50, 3, 3, 5, -53, -82, -101, -125,
444
72, 81, -40, 86, 53, 91, 114, 96,
445
28, -74, 123, 124, -44, -21, 81, -14,
446
-98, -43, 11, 90, -87, -106, 13, 63,
447
-62, 100, 111, 0, 0, 56, -64, 44,
448
-64, 48, 0, -97, -52, -87, -52, -88,
449
-52, -86, -64, 43, -64, 47, 0, -98,
450
-64, 36, -64, 40, 0, 107, -64, 35,
451
-64, 39, 0, 103, -64, 10, -64, 20,
452
0, 57, -64, 9, -64, 19, 0, 51,
453
0, -99, 0, -100, 0, 61, 0, 60,
454
0, 53, 0, 47, 0, -1, 1, 0,
455
0, 109, 0, 0, 0, 14, 0, 12,
456
0, 0, 9, 108, 111, 99, 97, 108,
457
104, 111, 115, 116, 0, 11, 0, 4,
458
3, 0, 1, 2, 0, 10, 0, 6,
459
0, 4, 0, 1, 0, 23, 0, 35,
460
0, 0, 0, 5, 0, 5, 1, 0,
461
0, 0, 0, 0, 22, 0, 0, 0,
462
23, 0, 0, 0, 13, 0, 48, 0,
463
46, 4, 3, 5, 3, 6, 3, 8,
464
7, 8, 8, 8, 9, 8, 10, 8,
465
11, 8, 4, 8, 5, 8, 6, 4,
466
1, 5, 1, 6, 1, 3, 3, 2,
467
3, 3, 1, 2, 1, 3, 2, 2,
468
2, 4, 2, 5, 2, 6, 2
469
};
470
471
public static interface TestCase {
472
void execTest() throws Exception;
473
}
474
475
private static final Map<String, TestCase> TESTMAP = new HashMap<>();
476
477
public static void main(String[] args) throws Exception {
478
boolean allGood = true;
479
System.setProperty("javax.net.debug", "ssl:handshake");
480
trustMgrFac = makeTrustManagerFactory(trustFilename, passwd);
481
keyMgrFac = makeKeyManagerFactory(keyFilename, passwd);
482
483
// Populate the test map
484
TESTMAP.put("noPskNoKexModes", noPskNoKexModes);
485
TESTMAP.put("noPskYesKexModes", noPskYesKexModes);
486
TESTMAP.put("yesPskNoKexModes", yesPskNoKexModes);
487
TESTMAP.put("yesPskYesKexModes", yesPskYesKexModes);
488
TESTMAP.put("supGroupsSect163k1", supGroupsSect163k1);
489
490
if (args == null || args.length < 1) {
491
throw new Exception("FAIL: Test @run line is missing a test label");
492
}
493
494
// Pull the test to run from the test map.
495
TestCase test = Objects.requireNonNull(TESTMAP.get(args[0]),
496
"No TestCase found for test label " + args[0]);
497
test.execTest();
498
}
499
500
/**
501
* Test case to cover hellos with no pre_shared_key nor
502
* psk_key_exchange_modes extensions. Clients not supporting PSK at all
503
* may send hellos like this.
504
*/
505
private static final TestCase noPskNoKexModes = new TestCase() {
506
@Override
507
public void execTest() throws Exception {
508
System.out.println("\nTest: PSK = No, PSKEX = No");
509
processClientHello("TLS", CLIHELLO_NOPSK_NOPSKEXMODE);
510
System.out.println("PASS");
511
}
512
};
513
514
/**
515
* Test case to cover hellos with no pre_shared_key but have the
516
* psk_key_exchange_modes extension. This kind of hello is seen from
517
* some popular browsers and test clients.
518
*/
519
private static final TestCase noPskYesKexModes = new TestCase() {
520
@Override
521
public void execTest() throws Exception {
522
System.out.println("\nTest: PSK = No, PSKEX = Yes");
523
processClientHello("TLS", CLIHELLO_NOPSK_YESPSKEXMODE);
524
System.out.println("PASS");
525
}
526
};
527
528
/**
529
* Test case using a client hello with the pre_shared_key extension but
530
* no psk_key_exchange_modes extension present. This is a violation of
531
* 8446 and should cause an exception when unwrapped and processed by
532
* SSLEngine.
533
*/
534
private static final TestCase yesPskNoKexModes = new TestCase() {
535
@Override
536
public void execTest() throws Exception {
537
try {
538
System.out.println("\nTest: PSK = Yes, PSKEX = No");
539
processClientHello("TLS", CLIHELLO_YESPSK_NOPSKEXMODE);
540
throw new Exception(
541
"FAIL: Client Hello processed without expected error");
542
} catch (SSLHandshakeException sslhe) {
543
System.out.println("PASS: Caught expected exception: " + sslhe);
544
}
545
}
546
};
547
548
/**
549
* Test case using a client hello asserting the pre_shared_key and
550
* psk_key_exchange_modes extensions.
551
*/
552
private static final TestCase yesPskYesKexModes = new TestCase() {
553
@Override
554
public void execTest() throws Exception {
555
System.out.println("\nTest: PSK = Yes, PSKEX = Yes");
556
processClientHello("TLS", CLIHELLO_YESPSK_YESPSKEXMODE);
557
System.out.println("PASS");
558
}
559
};
560
561
/**
562
* Test case with a client hello asserting two named curves in the
563
* supported_groups extension: sect163k1 and secp256r1.
564
*/
565
private static final TestCase supGroupsSect163k1 = new TestCase() {
566
@Override
567
public void execTest() throws Exception {
568
System.out.println("\nTest: Use of non-default-enabled " +
569
"Supported Group (sect163k1)");
570
processClientHello("TLS", CLIHELLO_SUPGRP_SECT163K1);
571
System.out.println("PASS");
572
}
573
};
574
575
/**
576
* Send a ClientHello message to an SSLEngine instance configured as a
577
* server.
578
*
579
* @param proto the protocol used to create the SSLContext. This will
580
* default to "TLS" if null is passed in.
581
* @param message the ClientHello as a complete TLS record.
582
*
583
* @throws Exception if any processing errors occur. The caller (TestCase)
584
* is expected to deal with the exception in whatever way appropriate
585
* for the test.
586
*/
587
private static void processClientHello(String proto, byte[] message)
588
throws Exception {
589
SSLEngine serverEng = makeServerEngine(proto, keyMgrFac, trustMgrFac);
590
ByteBuffer sTOc = makePacketBuf(serverEng);
591
SSLEngineResult serverResult;
592
593
ByteBuffer cTOs = ByteBuffer.wrap(message);
594
System.out.println("CLIENT-TO-SERVER\n" +
595
dumpHexBytes(cTOs, 16, "\n", " "));
596
serverResult = serverEng.unwrap(cTOs, SERVOUTBUF);
597
printResult("server unwrap: ", serverResult);
598
runDelegatedTasks(serverResult, serverEng);
599
serverEng.wrap(SERVOUTBUF, sTOc);
600
}
601
602
/**
603
* Create a TrustManagerFactory from a given keystore.
604
*
605
* @param tsPath the path to the trust store file.
606
* @param pass the password for the trust store.
607
*
608
* @return a new TrustManagerFactory built from the trust store provided.
609
*
610
* @throws GeneralSecurityException if any processing errors occur
611
* with the Keystore instantiation or TrustManagerFactory creation.
612
* @throws IOException if any loading error with the trust store occurs.
613
*/
614
private static TrustManagerFactory makeTrustManagerFactory(String tsPath,
615
String pass) throws GeneralSecurityException, IOException {
616
KeyStore ts = KeyStore.getInstance("JKS");
617
char[] passphrase = pass.toCharArray();
618
619
ts.load(new FileInputStream(tsPath), passphrase);
620
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
621
tmf.init(ts);
622
return tmf;
623
}
624
625
/**
626
* Create a KeyManagerFactory from a given keystore.
627
*
628
* @param ksPath the path to the keystore file.
629
* @param pass the password for the keystore.
630
*
631
* @return a new TrustManagerFactory built from the keystore provided.
632
*
633
* @throws GeneralSecurityException if any processing errors occur
634
* with the Keystore instantiation or KeyManagerFactory creation.
635
* @throws IOException if any loading error with the keystore occurs
636
*/
637
private static KeyManagerFactory makeKeyManagerFactory(String ksPath,
638
String pass) throws GeneralSecurityException, IOException {
639
KeyStore ks = KeyStore.getInstance("JKS");
640
char[] passphrase = pass.toCharArray();
641
642
ks.load(new FileInputStream(ksPath), passphrase);
643
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
644
kmf.init(ks, passphrase);
645
return kmf;
646
}
647
648
/**
649
* Create an SSLEngine instance from a given protocol specifier,
650
* KeyManagerFactory and TrustManagerFactory.
651
*
652
* @param proto the protocol specifier for the SSLContext. This will
653
* default to "TLS" if null is provided.
654
* @param kmf an initialized KeyManagerFactory. May be null.
655
* @param tmf an initialized TrustManagerFactory. May be null.
656
*
657
* @return an SSLEngine instance configured as a server and with client
658
* authentication disabled.
659
*
660
* @throws GeneralSecurityException if any errors occur during the
661
* creation of the SSLEngine.
662
*/
663
private static SSLEngine makeServerEngine(String proto,
664
KeyManagerFactory kmf, TrustManagerFactory tmf)
665
throws GeneralSecurityException {
666
SSLContext ctx = SSLContext.getInstance(proto != null ? proto : "TLS");
667
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
668
SSLEngine ssle = ctx.createSSLEngine();
669
ssle.setUseClientMode(false);
670
ssle.setNeedClientAuth(false);
671
return ssle;
672
}
673
674
/**
675
* Make a ByteBuffer sized for TLS records that can be used by an SSLEngine.
676
*
677
* @param engine the SSLEngine used to determine the packet buffer size.
678
*
679
* @return a ByteBuffer sized for TLS packets.
680
*/
681
private static ByteBuffer makePacketBuf(SSLEngine engine) {
682
SSLSession sess = engine.getSession();
683
ByteBuffer packetBuf = ByteBuffer.allocate(sess.getPacketBufferSize());
684
return packetBuf;
685
}
686
687
/**
688
* Runs any delegated tasks after unwrapping TLS records.
689
*
690
* @param result the most recent result from an unwrap operation on
691
* an SSLEngine.
692
* @param engine the SSLEngine used to unwrap the data.
693
*
694
* @throws Exception if any errors occur while running the delegated
695
* tasks.
696
*/
697
private static void runDelegatedTasks(SSLEngineResult result,
698
SSLEngine engine) throws Exception {
699
HandshakeStatus hsStatus = result.getHandshakeStatus();
700
if (hsStatus == HandshakeStatus.NEED_TASK) {
701
Runnable runnable;
702
while ((runnable = engine.getDelegatedTask()) != null) {
703
System.out.println("\trunning delegated task...");
704
runnable.run();
705
}
706
hsStatus = engine.getHandshakeStatus();
707
if (hsStatus == HandshakeStatus.NEED_TASK) {
708
throw new Exception(
709
"handshake shouldn't need additional tasks");
710
}
711
System.out.println("\tnew HandshakeStatus: " + hsStatus);
712
}
713
}
714
715
/**
716
* Display the results of a wrap or unwrap operation from an SSLEngine.
717
*
718
* @param str a label to be prefixed to the result display.
719
* @param result the result returned from the wrap/unwrap operation.
720
*/
721
private static void printResult(String str, SSLEngineResult result) {
722
System.out.println("The format of the SSLEngineResult is: \n" +
723
"\t\"getStatus() / getHandshakeStatus()\" +\n" +
724
"\t\"bytesConsumed() / bytesProduced()\"\n");
725
HandshakeStatus hsStatus = result.getHandshakeStatus();
726
System.out.println(str + result.getStatus() + "/" + hsStatus + ", " +
727
result.bytesConsumed() + "/" + result.bytesProduced() + " bytes");
728
if (hsStatus == HandshakeStatus.FINISHED) {
729
System.out.println("\t...ready for application data");
730
}
731
}
732
733
/**
734
* Dump the hex bytes of a buffer into string form.
735
*
736
* @param data The array of bytes to dump to stdout.
737
* @param itemsPerLine The number of bytes to display per line
738
* if the {@code lineDelim} character is blank then all bytes
739
* will be printed on a single line.
740
* @param lineDelim The delimiter between lines
741
* @param itemDelim The delimiter between bytes
742
*
743
* @return The hexdump of the byte array
744
*/
745
private static String dumpHexBytes(byte[] data, int itemsPerLine,
746
String lineDelim, String itemDelim) {
747
return dumpHexBytes(ByteBuffer.wrap(data), itemsPerLine, lineDelim,
748
itemDelim);
749
}
750
751
/**
752
* Dump the hex bytes of a buffer into string form.
753
*
754
* @param data The ByteBuffer to dump to stdout.
755
* @param itemsPerLine The number of bytes to display per line
756
* if the {@code lineDelim} character is blank then all bytes
757
* will be printed on a single line.
758
* @param lineDelim The delimiter between lines
759
* @param itemDelim The delimiter between bytes
760
*
761
* @return The hexdump of the byte array
762
*/
763
private static String dumpHexBytes(ByteBuffer data, int itemsPerLine,
764
String lineDelim, String itemDelim) {
765
StringBuilder sb = new StringBuilder();
766
if (data != null) {
767
data.mark();
768
int i = 0;
769
while (data.remaining() > 0) {
770
if (i % itemsPerLine == 0 && i != 0) {
771
sb.append(lineDelim);
772
}
773
sb.append(String.format("%02X", data.get())).append(itemDelim);
774
i++;
775
}
776
data.reset();
777
}
778
779
return sb.toString();
780
}
781
}
782
783