Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java
41152 views
1
/*
2
* Copyright (c) 2003, 2020, 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 7126889
27
* @summary Incorrect SSLEngine debug output
28
* @library /test/lib
29
* @run main DebugReportsOneExtraByte
30
*/
31
/*
32
* Debug output was reporting n+1 bytes of data was written when it was
33
* really was n.
34
*
35
* SunJSSE does not support dynamic system properties, no way to re-use
36
* system properties in samevm/agentvm mode.
37
*/
38
39
/**
40
* A SSLEngine usage example which simplifies the presentation
41
* by removing the I/O and multi-threading concerns.
42
*
43
* The test creates two SSLEngines, simulating a client and server.
44
* The "transport" layer consists two byte buffers: think of them
45
* as directly connected pipes.
46
*
47
* Note, this is a *very* simple example: real code will be much more
48
* involved. For example, different threading and I/O models could be
49
* used, transport mechanisms could close unexpectedly, and so on.
50
*
51
* When this application runs, notice that several messages
52
* (wrap/unwrap) pass before any application data is consumed or
53
* produced. (For more information, please see the SSL/TLS
54
* specifications.) There may several steps for a successful handshake,
55
* so it's typical to see the following series of operations:
56
*
57
* client server message
58
* ====== ====== =======
59
* wrap() ... ClientHello
60
* ... unwrap() ClientHello
61
* ... wrap() ServerHello/Certificate
62
* unwrap() ... ServerHello/Certificate
63
* wrap() ... ClientKeyExchange
64
* wrap() ... ChangeCipherSpec
65
* wrap() ... Finished
66
* ... unwrap() ClientKeyExchange
67
* ... unwrap() ChangeCipherSpec
68
* ... unwrap() Finished
69
* ... wrap() ChangeCipherSpec
70
* ... wrap() Finished
71
* unwrap() ... ChangeCipherSpec
72
* unwrap() ... Finished
73
*/
74
75
import javax.net.ssl.*;
76
import javax.net.ssl.SSLEngineResult.*;
77
import java.io.*;
78
import java.security.*;
79
import java.nio.*;
80
81
import jdk.test.lib.process.OutputAnalyzer;
82
import jdk.test.lib.process.ProcessTools;
83
import jdk.test.lib.security.SecurityUtils;
84
85
public class DebugReportsOneExtraByte {
86
87
/*
88
* Enables logging of the SSLEngine operations.
89
*/
90
private static boolean logging = true;
91
92
private SSLContext sslc;
93
94
private SSLEngine clientEngine; // client Engine
95
private ByteBuffer clientOut; // write side of clientEngine
96
private ByteBuffer clientIn; // read side of clientEngine
97
98
private SSLEngine serverEngine; // server Engine
99
private ByteBuffer serverOut; // write side of serverEngine
100
private ByteBuffer serverIn; // read side of serverEngine
101
102
/*
103
* For data transport, this example uses local ByteBuffers. This
104
* isn't really useful, but the purpose of this example is to show
105
* SSLEngine concepts, not how to do network transport.
106
*/
107
private ByteBuffer cTOs; // "reliable" transport client->server
108
private ByteBuffer sTOc; // "reliable" transport server->client
109
110
/*
111
* The following is to set up the keystores.
112
*/
113
private static String pathToStores = "../../../../javax/net/ssl/etc";
114
private static String keyStoreFile = "keystore";
115
private static String trustStoreFile = "truststore";
116
private static String passwd = "passphrase";
117
118
private static String keyFilename =
119
System.getProperty("test.src", ".") + "/" + pathToStores +
120
"/" + keyStoreFile;
121
private static String trustFilename =
122
System.getProperty("test.src", ".") + "/" + pathToStores +
123
"/" + trustStoreFile;
124
125
/*
126
* Main entry point for this test.
127
*/
128
public static void main(String args[]) throws Exception {
129
130
if (args.length == 0) {
131
OutputAnalyzer output = ProcessTools.executeTestJvm(
132
"-Dtest.src=" + System.getProperty("test.src"),
133
"-Djavax.net.debug=all", "DebugReportsOneExtraByte", "p");
134
output.shouldContain("WRITE: TLSv1 application_data, length = 8");
135
136
System.out.println("Test Passed.");
137
} else {
138
// Re-enable TLSv1 since test depends on it
139
SecurityUtils.removeFromDisabledTlsAlgs("TLSv1");
140
141
DebugReportsOneExtraByte test = new DebugReportsOneExtraByte();
142
test.runTest();
143
}
144
}
145
146
/*
147
* Create an initialized SSLContext to use for these tests.
148
*/
149
public DebugReportsOneExtraByte() throws Exception {
150
151
KeyStore ks = KeyStore.getInstance("JKS");
152
KeyStore ts = KeyStore.getInstance("JKS");
153
154
char[] passphrase = "passphrase".toCharArray();
155
156
ks.load(new FileInputStream(keyFilename), passphrase);
157
ts.load(new FileInputStream(trustFilename), passphrase);
158
159
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
160
kmf.init(ks, passphrase);
161
162
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
163
tmf.init(ts);
164
165
SSLContext sslCtx = SSLContext.getInstance("TLSv1");
166
167
sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
168
169
sslc = sslCtx;
170
}
171
172
/*
173
* Run the test.
174
*
175
* Sit in a tight loop, both engines calling wrap/unwrap regardless
176
* of whether data is available or not. We do this until both engines
177
* report back they are closed.
178
*
179
* The main loop handles all of the I/O phases of the SSLEngine's
180
* lifetime:
181
*
182
* initial handshaking
183
* application data transfer
184
* engine closing
185
*
186
* One could easily separate these phases into separate
187
* sections of code.
188
*/
189
private void runTest() throws Exception {
190
boolean dataDone = false;
191
192
createSSLEngines();
193
createBuffers();
194
195
SSLEngineResult clientResult; // results from client's last operation
196
SSLEngineResult serverResult; // results from server's last operation
197
198
/*
199
* Examining the SSLEngineResults could be much more involved,
200
* and may alter the overall flow of the application.
201
*
202
* For example, if we received a BUFFER_OVERFLOW when trying
203
* to write to the output pipe, we could reallocate a larger
204
* pipe, but instead we wait for the peer to drain it.
205
*/
206
207
/*
208
* Write one byte in first application packet, the rest
209
* will come later.
210
*/
211
serverOut.limit(1);
212
213
while (!isEngineClosed(clientEngine) ||
214
!isEngineClosed(serverEngine)) {
215
216
log("================");
217
218
clientResult = clientEngine.wrap(clientOut, cTOs);
219
log("client wrap: ", clientResult);
220
runDelegatedTasks(clientResult, clientEngine);
221
222
serverResult = serverEngine.wrap(serverOut, sTOc);
223
log("server wrap: ", serverResult);
224
runDelegatedTasks(serverResult, serverEngine);
225
226
// Next wrap will split.
227
if (serverOut.position() == 1) {
228
serverOut.limit(serverOut.capacity());
229
}
230
231
cTOs.flip();
232
sTOc.flip();
233
234
log("----");
235
236
clientResult = clientEngine.unwrap(sTOc, clientIn);
237
log("client unwrap: ", clientResult);
238
runDelegatedTasks(clientResult, clientEngine);
239
240
serverResult = serverEngine.unwrap(cTOs, serverIn);
241
log("server unwrap: ", serverResult);
242
runDelegatedTasks(serverResult, serverEngine);
243
244
cTOs.compact();
245
sTOc.compact();
246
247
/*
248
* After we've transfered all application data between the client
249
* and server, we close the clientEngine's outbound stream.
250
* This generates a close_notify handshake message, which the
251
* server engine receives and responds by closing itself.
252
*/
253
if (!dataDone && (clientOut.limit() == serverIn.position()) &&
254
(serverOut.limit() == clientIn.position())) {
255
256
/*
257
* A sanity check to ensure we got what was sent.
258
*/
259
checkTransfer(serverOut, clientIn);
260
checkTransfer(clientOut, serverIn);
261
262
log("\tClosing clientEngine's *OUTBOUND*...");
263
clientEngine.closeOutbound();
264
dataDone = true;
265
}
266
}
267
}
268
269
/*
270
* Using the SSLContext created during object creation,
271
* create/configure the SSLEngines we'll use for this test.
272
*/
273
private void createSSLEngines() throws Exception {
274
/*
275
* Configure the serverEngine to act as a server in the SSL/TLS
276
* handshake. Also, require SSL client authentication.
277
*/
278
serverEngine = sslc.createSSLEngine();
279
serverEngine.setUseClientMode(false);
280
serverEngine.setNeedClientAuth(true);
281
282
// Force a block-oriented ciphersuite.
283
serverEngine.setEnabledCipherSuites(
284
new String [] {"TLS_RSA_WITH_AES_128_CBC_SHA"});
285
286
/*
287
* Similar to above, but using client mode instead.
288
*/
289
clientEngine = sslc.createSSLEngine("client", 80);
290
clientEngine.setUseClientMode(true);
291
}
292
293
/*
294
* Create and size the buffers appropriately.
295
*/
296
private void createBuffers() {
297
298
/*
299
* We'll assume the buffer sizes are the same
300
* between client and server.
301
*/
302
SSLSession session = clientEngine.getSession();
303
int appBufferMax = session.getApplicationBufferSize();
304
int netBufferMax = session.getPacketBufferSize();
305
306
/*
307
* We'll make the input buffers a bit bigger than the max needed
308
* size, so that unwrap()s following a successful data transfer
309
* won't generate BUFFER_OVERFLOWS.
310
*
311
* We'll use a mix of direct and indirect ByteBuffers for
312
* tutorial purposes only. In reality, only use direct
313
* ByteBuffers when they give a clear performance enhancement.
314
*/
315
clientIn = ByteBuffer.allocate(appBufferMax + 50);
316
serverIn = ByteBuffer.allocate(appBufferMax + 50);
317
318
cTOs = ByteBuffer.allocateDirect(netBufferMax);
319
sTOc = ByteBuffer.allocateDirect(netBufferMax);
320
321
// No need to write anything on the client side, it will
322
// just confuse the output.
323
clientOut = ByteBuffer.wrap("".getBytes());
324
// 10 bytes long
325
serverOut = ByteBuffer.wrap("Hi Client!".getBytes());
326
}
327
328
/*
329
* If the result indicates that we have outstanding tasks to do,
330
* go ahead and run them in this thread.
331
*/
332
private static void runDelegatedTasks(SSLEngineResult result,
333
SSLEngine engine) throws Exception {
334
335
if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
336
Runnable runnable;
337
while ((runnable = engine.getDelegatedTask()) != null) {
338
log("\trunning delegated task...");
339
runnable.run();
340
}
341
HandshakeStatus hsStatus = engine.getHandshakeStatus();
342
if (hsStatus == HandshakeStatus.NEED_TASK) {
343
throw new Exception(
344
"handshake shouldn't need additional tasks");
345
}
346
log("\tnew HandshakeStatus: " + hsStatus);
347
}
348
}
349
350
private static boolean isEngineClosed(SSLEngine engine) {
351
return (engine.isOutboundDone() && engine.isInboundDone());
352
}
353
354
/*
355
* Simple check to make sure everything came across as expected.
356
*/
357
private static void checkTransfer(ByteBuffer a, ByteBuffer b)
358
throws Exception {
359
a.flip();
360
b.flip();
361
362
if (!a.equals(b)) {
363
throw new Exception("Data didn't transfer cleanly");
364
} else {
365
log("\tData transferred cleanly");
366
}
367
368
a.position(a.limit());
369
b.position(b.limit());
370
a.limit(a.capacity());
371
b.limit(b.capacity());
372
}
373
374
/*
375
* Logging code
376
*/
377
private static boolean resultOnce = true;
378
379
private static void log(String str, SSLEngineResult result) {
380
if (!logging) {
381
return;
382
}
383
if (resultOnce) {
384
resultOnce = false;
385
System.out.println("The format of the SSLEngineResult is: \n" +
386
"\t\"getStatus() / getHandshakeStatus()\" +\n" +
387
"\t\"bytesConsumed() / bytesProduced()\"\n");
388
}
389
HandshakeStatus hsStatus = result.getHandshakeStatus();
390
log(str +
391
result.getStatus() + "/" + hsStatus + ", " +
392
result.bytesConsumed() + "/" + result.bytesProduced() +
393
" bytes");
394
if (hsStatus == HandshakeStatus.FINISHED) {
395
log("\t...ready for application data");
396
}
397
}
398
399
private static void log(String str) {
400
if (logging) {
401
System.out.println(str);
402
}
403
}
404
}
405
406