Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/net/ssl/SSLEngine/EngineCloseOnAlert.java
41152 views
1
/*
2
* Copyright (c) 2004, 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
/*
25
* @test
26
* @bug 8133632
27
* @summary javax.net.ssl.SSLEngine does not properly handle received
28
* SSL fatal alerts
29
* @ignore the dependent implementation details are changed
30
* @run main/othervm EngineCloseOnAlert
31
*/
32
33
import java.io.FileInputStream;
34
import java.io.IOException;
35
import javax.net.ssl.*;
36
import java.nio.ByteBuffer;
37
import java.util.*;
38
import java.security.*;
39
import static javax.net.ssl.SSLEngineResult.HandshakeStatus.*;
40
41
public class EngineCloseOnAlert {
42
43
private static final String pathToStores = "../etc";
44
private static final String keyStoreFile = "keystore";
45
private static final String trustStoreFile = "truststore";
46
private static final String passwd = "passphrase";
47
private static final String keyFilename =
48
System.getProperty("test.src", ".") + "/" + pathToStores +
49
"/" + keyStoreFile;
50
private static final String trustFilename =
51
System.getProperty("test.src", ".") + "/" + pathToStores +
52
"/" + trustStoreFile;
53
54
private static KeyManagerFactory KMF;
55
private static TrustManagerFactory TMF;
56
private static TrustManagerFactory EMPTY_TMF;
57
58
private static final String[] TLS10ONLY = { "TLSv1" };
59
private static final String[] TLS12ONLY = { "TLSv1.2" };
60
private static final String[] ONECIPHER =
61
{ "TLS_RSA_WITH_AES_128_CBC_SHA" };
62
63
public interface TestCase {
64
public void runTest() throws Exception;
65
}
66
67
public static void main(String[] args) throws Exception {
68
int failed = 0;
69
List<TestCase> testMatrix = new LinkedList<TestCase>() {{
70
add(clientReceivesAlert);
71
add(serverReceivesAlert);
72
}};
73
74
// Create the various key/trust manager factories we'll need
75
createManagerFactories();
76
77
for (TestCase test : testMatrix) {
78
try {
79
test.runTest();
80
} catch (Exception e) {
81
System.out.println("Exception in test:\n" + e);
82
e.printStackTrace(System.out);
83
failed++;
84
}
85
}
86
87
System.out.println("Total tests: " + testMatrix.size() + ", passed: " +
88
(testMatrix.size() - failed) + ", failed: " + failed);
89
if (failed > 0) {
90
throw new RuntimeException("One or more tests failed.");
91
}
92
}
93
94
private static final TestCase clientReceivesAlert = new TestCase() {
95
@Override
96
public void runTest() throws Exception {
97
System.out.println("");
98
System.out.println("=======================================");
99
System.out.println("Test: Client receives alert from server");
100
System.out.println("=======================================");
101
102
// For this test, we won't initialize any keystore so the
103
// server will throw an exception because it has no key/cert to
104
// match the requested ciphers offered by the client. This
105
// will generate an alert from the server to the client.
106
107
SSLContext context = SSLContext.getDefault();
108
SSLEngine client = context.createSSLEngine();
109
SSLEngine server = context.createSSLEngine();
110
client.setUseClientMode(true);
111
server.setUseClientMode(false);
112
SSLEngineResult clientResult;
113
SSLEngineResult serverResult;
114
115
ByteBuffer raw = ByteBuffer.allocate(32768);
116
ByteBuffer plain = ByteBuffer.allocate(32768);
117
118
// Generate the client hello and have the server unwrap it
119
client.wrap(plain, raw);
120
checkEngineState(client, NEED_UNWRAP, false, false);
121
raw.flip();
122
System.out.println("Client-to-Server:\n-----------------\n" +
123
dumpHexBytes(raw, 16, "\n", ":"));
124
125
126
// The server should need to run a delegated task while processing
127
// the client hello data.
128
serverResult = server.unwrap(raw, plain);
129
checkEngineState(server, NEED_TASK, false, false);
130
System.out.println("Server result: " + serverResult);
131
runDelegatedTasks(serverResult, server);
132
checkEngineState(server, NEED_WRAP, true, false);
133
134
try {
135
raw.clear();
136
serverResult = server.wrap(plain, raw);
137
System.out.println("Server result: " + serverResult);
138
runDelegatedTasks(serverResult, server);
139
} catch (SSLException e) {
140
// This is the expected code path
141
System.out.println("Server throws exception: " + e);
142
System.out.println("Server engine state: " +
143
"isInboundDone = "+ server.isInboundDone() +
144
", isOutboundDone = " + server.isOutboundDone() +
145
", handshake status = " + server.getHandshakeStatus());
146
checkEngineState(server, NEED_WRAP, true, false);
147
}
148
raw.clear();
149
150
// The above should show that isInboundDone returns true, and
151
// handshake status is NEED_WRAP. That is the correct behavior,
152
// wrap will put a fatal alert message in the buffer.
153
serverResult = server.wrap(plain, raw);
154
System.out.println("Server result (wrap after exception): " +
155
serverResult);
156
System.out.println("Server engine closure state: isInboundDone="
157
+ server.isInboundDone() + ", isOutboundDone="
158
+ server.isOutboundDone());
159
checkEngineState(server, NEED_UNWRAP, true, true);
160
raw.flip();
161
162
System.out.println("Server-to-Client:\n-----------------\n" +
163
dumpHexBytes(raw, 16, "\n", ":"));
164
165
// Client side will read the fatal alert and throw exception.
166
try {
167
clientResult = client.unwrap(raw, plain);
168
System.out.println("Client result (unwrap alert): " +
169
clientResult);
170
} catch (SSLException e) {
171
System.out.println("Client throws exception: " + e);
172
System.out.println("Engine closure status: isInboundDone="
173
+ client.isInboundDone() + ", isOutboundDone="
174
+ client.isOutboundDone() + ", handshake status="
175
+ client.getHandshakeStatus());
176
checkEngineState(client, NOT_HANDSHAKING, true, true);
177
}
178
raw.clear();
179
180
// Last test, we try to unwrap
181
clientResult = client.unwrap(raw, plain);
182
checkEngineState(client, NOT_HANDSHAKING, true, true);
183
System.out.println("Client result (wrap after exception): " +
184
clientResult);
185
}
186
};
187
188
private static final TestCase serverReceivesAlert = new TestCase() {
189
@Override
190
public void runTest() throws Exception {
191
SSLContext cliContext = SSLContext.getDefault();
192
SSLContext servContext = SSLContext.getInstance("TLS");
193
servContext.init(KMF.getKeyManagers(), TMF.getTrustManagers(),
194
null);
195
SSLEngine client = cliContext.createSSLEngine();
196
SSLEngine server = servContext.createSSLEngine();
197
client.setUseClientMode(true);
198
client.setEnabledProtocols(TLS12ONLY);
199
client.setEnabledCipherSuites(ONECIPHER);
200
server.setUseClientMode(false);
201
server.setEnabledProtocols(TLS10ONLY);
202
SSLEngineResult clientResult;
203
SSLEngineResult serverResult;
204
ByteBuffer raw = ByteBuffer.allocate(32768);
205
ByteBuffer plain = ByteBuffer.allocate(32768);
206
207
System.out.println("");
208
System.out.println("=======================================");
209
System.out.println("Test: Server receives alert from client");
210
System.out.println("=======================================");
211
212
// Generate the client hello and have the server unwrap it
213
checkEngineState(client, NOT_HANDSHAKING, false, false);
214
client.wrap(plain, raw);
215
checkEngineState(client, NEED_UNWRAP, false, false);
216
raw.flip();
217
System.out.println("Client-to-Server:\n-----------------\n" +
218
dumpHexBytes(raw, 16, "\n", ":"));
219
220
// The server should need to run a delegated task while processing
221
// the client hello data.
222
serverResult = server.unwrap(raw, plain);
223
checkEngineState(server, NEED_TASK, false, false);
224
runDelegatedTasks(serverResult, server);
225
checkEngineState(server, NEED_WRAP, false, false);
226
raw.compact();
227
228
// The server should now wrap the response back to the client
229
server.wrap(plain, raw);
230
checkEngineState(server, NEED_UNWRAP, false, false);
231
raw.flip();
232
System.out.println("Server-to-Client:\n-----------------\n" +
233
dumpHexBytes(raw, 16, "\n", ":"));
234
235
// The client should parse this and throw an exception because
236
// It is unwiling to do TLS 1.0
237
clientResult = client.unwrap(raw, plain);
238
checkEngineState(client, NEED_TASK, false, false);
239
runDelegatedTasks(clientResult, client);
240
checkEngineState(client, NEED_UNWRAP, false, false);
241
242
try {
243
client.unwrap(raw, plain);
244
} catch (SSLException e) {
245
System.out.println("Client throws exception: " + e);
246
System.out.println("Engine closure status: isInboundDone="
247
+ client.isInboundDone() + ", isOutboundDone="
248
+ client.isOutboundDone() + ", handshake status="
249
+ client.getHandshakeStatus());
250
checkEngineState(client, NEED_WRAP, true, false);
251
}
252
raw.clear();
253
254
// Now the client should wrap the exception
255
client.wrap(plain, raw);
256
checkEngineState(client, NEED_UNWRAP, true, true);
257
raw.flip();
258
System.out.println("Client-to-Server:\n-----------------\n" +
259
dumpHexBytes(raw, 16, "\n", ":"));
260
261
try {
262
server.unwrap(raw, plain);
263
checkEngineState(server, NEED_UNWRAP, false, false);
264
} catch (SSLException e) {
265
System.out.println("Server throws exception: " + e);
266
System.out.println("Engine closure status: isInboundDone="
267
+ server.isInboundDone() + ", isOutboundDone="
268
+ server.isOutboundDone() + ", handshake status="
269
+ server.getHandshakeStatus());
270
checkEngineState(server, NOT_HANDSHAKING, true, true);
271
}
272
raw.clear();
273
}
274
};
275
276
277
/*
278
* If the result indicates that we have outstanding tasks to do,
279
* go ahead and run them in this thread.
280
*/
281
private static void runDelegatedTasks(SSLEngineResult result,
282
SSLEngine engine) throws Exception {
283
284
if (result.getHandshakeStatus() ==
285
SSLEngineResult.HandshakeStatus.NEED_TASK) {
286
Runnable runnable;
287
while ((runnable = engine.getDelegatedTask()) != null) {
288
System.out.println("\trunning delegated task...");
289
runnable.run();
290
}
291
SSLEngineResult.HandshakeStatus hsStatus =
292
engine.getHandshakeStatus();
293
if (hsStatus == SSLEngineResult.HandshakeStatus.NEED_TASK) {
294
throw new Exception(
295
"handshake shouldn't need additional tasks");
296
}
297
System.out.println("\tnew HandshakeStatus: " + hsStatus);
298
}
299
}
300
301
/**
302
*
303
* @param data The array of bytes to dump to stdout.
304
* @param itemsPerLine The number of bytes to display per line
305
* if the {@code lineDelim} character is blank then all bytes will be
306
* printed on a single line.
307
* @param lineDelim The delimiter between lines
308
* @param itemDelim The delimiter between bytes
309
*
310
* @return The hexdump of the byte array
311
*/
312
private static String dumpHexBytes(ByteBuffer data, int itemsPerLine,
313
String lineDelim, String itemDelim) {
314
StringBuilder sb = new StringBuilder();
315
316
if (data != null) {
317
data.mark();
318
for (int i = 0; i < data.limit(); i++) {
319
if (i % itemsPerLine == 0 && i != 0) {
320
sb.append(lineDelim);
321
}
322
sb.append(String.format("%02X", data.get(i)));
323
if (i % itemsPerLine != (itemsPerLine - 1) &&
324
i != (data.limit() -1)) {
325
sb.append(itemDelim);
326
}
327
}
328
data.reset();
329
}
330
331
return sb.toString();
332
}
333
334
private static void createManagerFactories()
335
throws GeneralSecurityException, IOException {
336
KeyStore keystore = KeyStore.getInstance("PKCS12");
337
KeyStore truststore = KeyStore.getInstance("PKCS12");
338
KeyStore empty_ts = KeyStore.getInstance("PKCS12");
339
char[] passphrase = passwd.toCharArray();
340
341
keystore.load(new FileInputStream(keyFilename), passphrase);
342
truststore.load(new FileInputStream(trustFilename), passphrase);
343
empty_ts.load(null, "".toCharArray());
344
345
KMF = KeyManagerFactory.getInstance("PKIX");
346
KMF.init(keystore, passphrase);
347
TMF = TrustManagerFactory.getInstance("PKIX");
348
TMF.init(truststore);
349
EMPTY_TMF = TrustManagerFactory.getInstance("PKIX");
350
EMPTY_TMF.init(truststore);
351
}
352
353
private static void checkEngineState(SSLEngine engine,
354
SSLEngineResult.HandshakeStatus expectedHSStat,
355
boolean expectedInboundDone, boolean expectedOutboundDone) {
356
if (engine.getHandshakeStatus() != expectedHSStat ||
357
engine.isInboundDone() != expectedInboundDone ||
358
engine.isOutboundDone() != expectedOutboundDone) {
359
throw new RuntimeException("Error: engine not in expected state\n" +
360
"Expected: state = " + expectedHSStat +
361
", inDone = " + expectedInboundDone +
362
", outDone = " + expectedOutboundDone + "\n" +
363
"Actual: state = " + engine.getHandshakeStatus() +
364
", inDone = " + engine.isInboundDone() +
365
", outDone = " + engine.isOutboundDone());
366
} else {
367
System.out.println((engine.getUseClientMode() ?
368
"Client" : "Server") + " handshake status: " +
369
engine.getHandshakeStatus() + ", inDone = " +
370
engine.isInboundDone() + ", outDone = " +
371
engine.isOutboundDone());
372
}
373
}
374
}
375
376