Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/sun/security/ssl/CipherSuite/NoDesRC4CiphSuite.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 8208350
27
* @summary Disable all DES cipher suites
28
* @run main/othervm NoDesRC4CiphSuite
29
*/
30
31
/*
32
* SunJSSE does not support dynamic system properties, no way to re-use
33
* system properties in samevm/agentvm mode.
34
*/
35
36
import java.security.Security;
37
import javax.net.ssl.*;
38
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
39
import java.io.IOException;
40
import java.nio.ByteBuffer;
41
import java.security.GeneralSecurityException;
42
import java.util.List;
43
import java.util.ArrayList;
44
import java.util.Arrays;
45
46
public class NoDesRC4CiphSuite {
47
48
private static final boolean DEBUG = false;
49
50
private static final byte RECTYPE_HS = 0x16;
51
private static final byte HSMSG_CLIHELLO = 0x01;
52
53
// These are some groups of Cipher Suites by names and IDs
54
private static final List<Integer> DES_CS_LIST = Arrays.asList(
55
0x0009, 0x0015, 0x0012, 0x001A, 0x0008, 0x0014, 0x0011, 0x0019
56
);
57
private static final String[] DES_CS_LIST_NAMES = new String[] {
58
"SSL_RSA_WITH_DES_CBC_SHA",
59
"SSL_DHE_RSA_WITH_DES_CBC_SHA",
60
"SSL_DHE_DSS_WITH_DES_CBC_SHA",
61
"SSL_DH_anon_WITH_DES_CBC_SHA",
62
"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
63
"SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
64
"SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
65
"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"
66
};
67
private static final List<Integer> RC4_CS_LIST = Arrays.asList(
68
0xC007, 0xC011, 0x0005, 0xC002, 0xC00C, 0x0004, 0xC016, 0x0018,
69
0x0003, 0x0017
70
);
71
private static final String[] RC4_CS_LIST_NAMES = new String[] {
72
"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
73
"TLS_ECDHE_RSA_WITH_RC4_128_SHA",
74
"SSL_RSA_WITH_RC4_128_SHA",
75
"TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
76
"TLS_ECDH_RSA_WITH_RC4_128_SHA",
77
"SSL_RSA_WITH_RC4_128_MD5",
78
"TLS_ECDH_anon_WITH_RC4_128_SHA",
79
"SSL_DH_anon_WITH_RC4_128_MD5",
80
"SSL_RSA_EXPORT_WITH_RC4_40_MD5",
81
"SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"
82
};
83
84
private static final ByteBuffer CLIOUTBUF =
85
ByteBuffer.wrap("Client Side".getBytes());
86
87
public static void main(String[] args) throws Exception {
88
boolean allGood = true;
89
String disAlg = Security.getProperty("jdk.tls.disabledAlgorithms");
90
System.err.println("Disabled Algs: " + disAlg);
91
92
// Disabled DES tests
93
allGood &= testDefaultCase(DES_CS_LIST);
94
allGood &= testEngAddDisabled(DES_CS_LIST_NAMES, DES_CS_LIST);
95
allGood &= testEngOnlyDisabled(DES_CS_LIST_NAMES);
96
97
// Disabled RC4 tests
98
allGood &= testDefaultCase(RC4_CS_LIST);
99
allGood &= testEngAddDisabled(RC4_CS_LIST_NAMES, RC4_CS_LIST);
100
allGood &= testEngOnlyDisabled(RC4_CS_LIST_NAMES);
101
102
if (allGood) {
103
System.err.println("All tests passed");
104
} else {
105
throw new RuntimeException("One or more tests failed");
106
}
107
}
108
109
/**
110
* Create an engine with the default set of cipher suites enabled and make
111
* sure none of the disabled suites are present in the client hello.
112
*
113
* @param disabledSuiteIds the {@code List} of disabled cipher suite IDs
114
* to be checked for.
115
*
116
* @return true if the test passed (No disabled suites), false otherwise
117
*/
118
private static boolean testDefaultCase(List<Integer> disabledSuiteIds)
119
throws Exception {
120
System.err.println("\nTest: Default SSLEngine suite set");
121
SSLEngine ssle = makeEngine();
122
if (DEBUG) {
123
listCiphers("Suite set upon creation", ssle);
124
}
125
SSLEngineResult clientResult;
126
ByteBuffer cTOs = makeClientBuf(ssle);
127
clientResult = ssle.wrap(CLIOUTBUF, cTOs);
128
if (DEBUG) {
129
dumpResult("ClientHello: ", clientResult);
130
}
131
cTOs.flip();
132
boolean foundSuite = areSuitesPresentCH(cTOs, disabledSuiteIds);
133
if (foundSuite) {
134
System.err.println("FAIL: Found disabled suites!");
135
return false;
136
} else {
137
System.err.println("PASS: No disabled suites found.");
138
return true;
139
}
140
}
141
142
/**
143
* Create an engine and set only disabled cipher suites.
144
* The engine should not create the client hello message since the only
145
* available suites to assert in the client hello are disabled ones.
146
*
147
* @param disabledSuiteNames an array of cipher suite names that
148
* should be disabled cipher suites.
149
*
150
* @return true if the engine throws SSLHandshakeException during client
151
* hello creation, false otherwise.
152
*/
153
private static boolean testEngOnlyDisabled(String[] disabledSuiteNames)
154
throws Exception {
155
System.err.println(
156
"\nTest: SSLEngine configured with only disabled suites");
157
try {
158
SSLEngine ssle = makeEngine();
159
ssle.setEnabledCipherSuites(disabledSuiteNames);
160
if (DEBUG) {
161
listCiphers("Suite set upon creation", ssle);
162
}
163
SSLEngineResult clientResult;
164
ByteBuffer cTOs = makeClientBuf(ssle);
165
clientResult = ssle.wrap(CLIOUTBUF, cTOs);
166
if (DEBUG) {
167
dumpResult("ClientHello: ", clientResult);
168
}
169
cTOs.flip();
170
} catch (SSLHandshakeException shse) {
171
System.err.println("PASS: Caught expected exception: " + shse);
172
return true;
173
}
174
System.err.println("FAIL: Expected SSLHandshakeException not thrown");
175
return false;
176
}
177
178
/**
179
* Create an engine and add some disabled suites to the default
180
* set of cipher suites. Make sure none of the disabled suites show up
181
* in the client hello even though they were explicitly added.
182
*
183
* @param disabledSuiteNames an array of cipher suite names that
184
* should be disabled cipher suites.
185
* @param disabledIds the {@code List} of disabled cipher suite IDs
186
* to be checked for.
187
*
188
* @return true if the test passed (No disabled suites), false otherwise
189
*/
190
private static boolean testEngAddDisabled(String[] disabledNames,
191
List<Integer> disabledIds) throws Exception {
192
System.err.println("\nTest: SSLEngine with disabled suites added");
193
SSLEngine ssle = makeEngine();
194
195
// Add disabled suites to the existing engine's set of enabled suites
196
String[] initialSuites = ssle.getEnabledCipherSuites();
197
String[] plusDisSuites = Arrays.copyOf(initialSuites,
198
initialSuites.length + disabledNames.length);
199
System.arraycopy(disabledNames, 0, plusDisSuites,
200
initialSuites.length, disabledNames.length);
201
ssle.setEnabledCipherSuites(plusDisSuites);
202
203
if (DEBUG) {
204
listCiphers("Suite set upon creation", ssle);
205
}
206
SSLEngineResult clientResult;
207
ByteBuffer cTOs = makeClientBuf(ssle);
208
clientResult = ssle.wrap(CLIOUTBUF, cTOs);
209
if (DEBUG) {
210
dumpResult("ClientHello: ", clientResult);
211
}
212
cTOs.flip();
213
boolean foundDisabled = areSuitesPresentCH(cTOs, disabledIds);
214
if (foundDisabled) {
215
System.err.println("FAIL: Found disabled suites!");
216
return false;
217
} else {
218
System.err.println("PASS: No disabled suites found.");
219
return true;
220
}
221
}
222
223
private static SSLEngine makeEngine() throws GeneralSecurityException {
224
SSLContext ctx = SSLContext.getInstance("TLSv1.2");
225
ctx.init(null, null, null);
226
return ctx.createSSLEngine();
227
}
228
229
private static ByteBuffer makeClientBuf(SSLEngine ssle) {
230
ssle.setUseClientMode(true);
231
ssle.setNeedClientAuth(false);
232
SSLSession sess = ssle.getSession();
233
ByteBuffer cTOs = ByteBuffer.allocateDirect(sess.getPacketBufferSize());
234
return cTOs;
235
}
236
237
private static void listCiphers(String prefix, SSLEngine ssle) {
238
System.err.println(prefix + "\n---------------");
239
String[] suites = ssle.getEnabledCipherSuites();
240
for (String suite : suites) {
241
System.err.println(suite);
242
}
243
System.err.println("---------------");
244
}
245
246
/**
247
* Walk a TLS 1.2 or earlier ClientHello looking for any of the suites
248
* in the suiteIdList.
249
*
250
* @param clientHello a ByteBuffer containing the ClientHello message as
251
* a complete TLS record. The position of the buffer should be
252
* at the first byte of the TLS record header.
253
* @param suiteIdList a List of integer values corresponding to
254
* TLS cipher suite identifiers.
255
*
256
* @return true if at least one of the suites in {@code suiteIdList}
257
* is found in the ClientHello's cipher suite list
258
*
259
* @throws IOException if the data in the {@code clientHello}
260
* buffer is not a TLS handshake message or is not a client hello.
261
*/
262
private static boolean areSuitesPresentCH(ByteBuffer clientHello,
263
List<Integer> suiteIdList) throws IOException {
264
byte val;
265
266
// Process the TLS Record
267
val = clientHello.get();
268
if (val != RECTYPE_HS) {
269
throw new IOException(
270
"Not a handshake record, type = " + val);
271
}
272
273
// Just skip over the version and length
274
clientHello.position(clientHello.position() + 4);
275
276
// Check the handshake message type
277
val = clientHello.get();
278
if (val != HSMSG_CLIHELLO) {
279
throw new IOException(
280
"Not a ClientHello handshake message, type = " + val);
281
}
282
283
// Skip over the length
284
clientHello.position(clientHello.position() + 3);
285
286
// Skip over the protocol version (2) and random (32);
287
clientHello.position(clientHello.position() + 34);
288
289
// Skip past the session ID (variable length <= 32)
290
int len = Byte.toUnsignedInt(clientHello.get());
291
if (len > 32) {
292
throw new IOException("Session ID is too large, len = " + len);
293
}
294
clientHello.position(clientHello.position() + len);
295
296
// Finally, we are at the cipher suites. Walk the list and place them
297
// into a List.
298
int csLen = Short.toUnsignedInt(clientHello.getShort());
299
if (csLen % 2 != 0) {
300
throw new IOException("CipherSuite length is invalid, len = " +
301
csLen);
302
}
303
int csCount = csLen / 2;
304
List<Integer> csSuiteList = new ArrayList<>(csCount);
305
log("Found following suite IDs in hello:");
306
for (int i = 0; i < csCount; i++) {
307
int curSuite = Short.toUnsignedInt(clientHello.getShort());
308
log(String.format("Suite ID: 0x%04x", curSuite));
309
csSuiteList.add(curSuite);
310
}
311
312
// Now check to see if any of the suites passed in match what is in
313
// the suite list.
314
boolean foundMatch = false;
315
for (Integer cs : suiteIdList) {
316
if (csSuiteList.contains(cs)) {
317
System.err.format("Found match for suite ID 0x%04x\n", cs);
318
foundMatch = true;
319
break;
320
}
321
}
322
323
// We don't care about the rest of the ClientHello message.
324
// Rewind and return whether we found a match or not.
325
clientHello.rewind();
326
return foundMatch;
327
}
328
329
private static void dumpResult(String str, SSLEngineResult result) {
330
System.err.println("The format of the SSLEngineResult is: \n" +
331
"\t\"getStatus() / getHandshakeStatus()\" +\n" +
332
"\t\"bytesConsumed() / bytesProduced()\"\n");
333
HandshakeStatus hsStatus = result.getHandshakeStatus();
334
System.err.println(str + result.getStatus() + "/" + hsStatus + ", " +
335
result.bytesConsumed() + "/" + result.bytesProduced() + " bytes");
336
if (hsStatus == HandshakeStatus.FINISHED) {
337
System.err.println("\t...ready for application data");
338
}
339
}
340
341
private static void log(String str) {
342
if (DEBUG) {
343
System.err.println(str);
344
}
345
}
346
}
347
348