Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/net/ssl/SSLEngine/SSLEngineService.java
41152 views
1
/*
2
* Copyright (c) 2006, 2012, 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
* @bug 6388456
26
* @summary Need adjustable TLS max record size for interoperability
27
* with non-compliant stacks
28
*
29
* Helper class of SSL/TLS client/server communication.
30
*
31
* @author Xuelei Fan
32
*/
33
34
import javax.net.ssl.*;
35
36
import java.io.*;
37
import java.security.*;
38
import java.nio.*;
39
import java.nio.channels.*;
40
41
public class SSLEngineService {
42
43
private static String keyStoreFile = "keystore";
44
private static String trustStoreFile = "truststore";
45
private static char[] passphrase = "passphrase".toCharArray();
46
47
private String pathToStores;
48
private String keyFilename;
49
private String trustFilename;
50
51
protected SSLEngineService() {
52
init("../etc");
53
}
54
55
protected SSLEngineService(String pathToStores) {
56
init(pathToStores);
57
}
58
59
private void init(String pathToStores) {
60
this.pathToStores = pathToStores;
61
this.keyFilename =
62
System.getProperty("test.src", "./") + "/" + pathToStores +
63
"/" + keyStoreFile;
64
this.trustFilename =
65
System.getProperty("test.src", "./") + "/" + pathToStores +
66
"/" + trustStoreFile;
67
}
68
69
// deliver local application data.
70
protected static void deliver(SSLEngine ssle, SocketChannel sc)
71
throws Exception {
72
73
// create buufer.
74
int appBufferMax = ssle.getSession().getApplicationBufferSize();
75
int netBufferMax = ssle.getSession().getPacketBufferSize();
76
int length = appBufferMax * (Integer.SIZE / 8);
77
78
// allocate more in order to check large packet
79
ByteBuffer localAppData = ByteBuffer.allocate(length);
80
81
// allocate less in order to check BUFFER_OVERFLOW/BUFFER_UNDERFLOW
82
ByteBuffer localNetData = ByteBuffer.allocate(netBufferMax/2);
83
84
// prepare local application data
85
localAppData.putInt(length);
86
for (int i = 1; i < appBufferMax; i++) {
87
localAppData.putInt(i);
88
}
89
localAppData.flip();
90
91
92
while (localAppData.hasRemaining()) {
93
// empty the local network packet buffer.
94
localNetData.clear();
95
96
// generated local network packet.
97
SSLEngineResult res = ssle.wrap(localAppData, localNetData);
98
99
// checking status
100
switch (res.getStatus()) {
101
102
case OK :
103
localNetData.flip();
104
105
// send the network packet
106
while (localNetData.hasRemaining()) {
107
if (sc.write(localNetData) < 0) {
108
throw new IOException("Unable write to socket channel");
109
}
110
}
111
112
if (res.getHandshakeStatus() ==
113
SSLEngineResult.HandshakeStatus.NEED_TASK) {
114
Runnable runnable;
115
while ((runnable = ssle.getDelegatedTask()) != null) {
116
runnable.run();
117
}
118
}
119
120
// detect large buffer
121
if (res.bytesProduced() >= Short.MAX_VALUE) {
122
System.out.println("Generate a " +
123
res.bytesProduced() + " bytes large packet ");
124
}
125
break;
126
127
case BUFFER_OVERFLOW :
128
// maybe need to enlarge the local network packet buffer.
129
int size = ssle.getSession().getPacketBufferSize();
130
if (size > localNetData.capacity()) {
131
System.out.println("resize destination buffer upto " +
132
size + " bytes for BUFFER_OVERFLOW");
133
localNetData = enlargeBuffer(localNetData, size);
134
}
135
break;
136
137
default : // BUFFER_UNDERFLOW or CLOSED :
138
throw new IOException("Received invalid" + res.getStatus() +
139
"during transfer application data");
140
}
141
}
142
}
143
144
145
// receive peer application data.
146
protected static void receive(SSLEngine ssle, SocketChannel sc)
147
throws Exception {
148
149
// create buufers.
150
int appBufferMax = ssle.getSession().getApplicationBufferSize();
151
int netBufferMax = ssle.getSession().getPacketBufferSize();
152
153
// allocate less in order to check BUFFER_OVERFLOW/BUFFER_UNDERFLOW
154
ByteBuffer peerAppData = ByteBuffer.allocate(appBufferMax/2);
155
ByteBuffer peerNetData = ByteBuffer.allocate(netBufferMax/2);
156
int received = -1;
157
158
boolean needToReadMore = true;
159
while (received != 0) {
160
if (needToReadMore) {
161
if (ssle.isInboundDone() || sc.read(peerNetData) < 0) {
162
break;
163
}
164
}
165
166
peerNetData.flip();
167
SSLEngineResult res = ssle.unwrap(peerNetData, peerAppData);
168
peerNetData.compact();
169
170
// checking status
171
switch (res.getStatus()) {
172
173
case OK :
174
if (res.getHandshakeStatus() ==
175
SSLEngineResult.HandshakeStatus.NEED_TASK) {
176
Runnable runnable;
177
while ((runnable = ssle.getDelegatedTask()) != null) {
178
runnable.run();
179
}
180
}
181
182
if (received < 0 && res.bytesProduced() < 4 ) {
183
break;
184
}
185
186
if (received < 0) {
187
received = peerAppData.getInt(0);
188
}
189
190
System.out.println("received " + peerAppData.position() +
191
" bytes client application data");
192
System.out.println("\tcomsumed " + res.bytesConsumed() +
193
" byes network data");
194
peerAppData.clear();
195
196
received -= res.bytesProduced();
197
198
// detect large buffer
199
if (res.bytesConsumed() >= Short.MAX_VALUE) {
200
System.out.println("Consumes a " + res.bytesConsumed() +
201
" bytes large packet ");
202
}
203
204
needToReadMore = (peerNetData.position() > 0) ? false : true;
205
206
break;
207
208
case BUFFER_OVERFLOW :
209
// maybe need to enlarge the peer application data buffer.
210
int size = ssle.getSession().getApplicationBufferSize();
211
if (size > peerAppData.capacity()) {
212
System.out.println("resize destination buffer upto " +
213
size + " bytes for BUFFER_OVERFLOW");
214
peerAppData = enlargeBuffer(peerAppData, size);
215
}
216
break;
217
218
case BUFFER_UNDERFLOW :
219
// maybe need to enlarge the peer network packet data buffer.
220
size = ssle.getSession().getPacketBufferSize();
221
if (size > peerNetData.capacity()) {
222
System.out.println("resize source buffer upto " + size +
223
" bytes for BUFFER_UNDERFLOW");
224
peerNetData = enlargeBuffer(peerNetData, size);
225
}
226
227
needToReadMore = true;
228
break;
229
230
default : // CLOSED :
231
throw new IOException("Received invalid" + res.getStatus() +
232
"during transfer application data");
233
}
234
}
235
}
236
237
protected static void handshaking(SSLEngine ssle, SocketChannel sc,
238
ByteBuffer additional) throws Exception {
239
240
int appBufferMax = ssle.getSession().getApplicationBufferSize();
241
int netBufferMax = ssle.getSession().getPacketBufferSize();
242
243
// allocate less in order to check BUFFER_OVERFLOW/BUFFER_UNDERFLOW
244
ByteBuffer localAppData = ByteBuffer.allocate(appBufferMax/10);
245
ByteBuffer peerAppData = ByteBuffer.allocate(appBufferMax/10);
246
ByteBuffer localNetData = ByteBuffer.allocate(netBufferMax/10);
247
ByteBuffer peerNetData = ByteBuffer.allocate(netBufferMax/10);
248
249
// begin handshake
250
ssle.beginHandshake();
251
SSLEngineResult.HandshakeStatus hs = ssle.getHandshakeStatus();
252
253
// start handshaking from unwrap
254
byte[] buffer = new byte[0xFF];
255
boolean underflow = false;
256
do {
257
switch (hs) {
258
259
case NEED_UNWRAP :
260
if (peerNetData.position() == 0) {
261
if (additional != null && additional.hasRemaining()) {
262
do {
263
int len = Math.min(buffer.length,
264
peerNetData.remaining());
265
len = Math.min(len, additional.remaining());
266
if (len != 0) {
267
additional.get(buffer, 0, len);
268
peerNetData.put(buffer, 0, len);
269
}
270
} while (peerNetData.remaining() > 0 &&
271
additional.hasRemaining());
272
} else {
273
if (sc.read(peerNetData) < 0) {
274
ssle.closeInbound();
275
return;
276
}
277
}
278
}
279
280
if (underflow) {
281
if (sc.read(peerNetData) < 0) {
282
ssle.closeInbound();
283
return;
284
}
285
286
underflow = false;
287
}
288
289
peerNetData.flip();
290
SSLEngineResult res = ssle.unwrap(peerNetData, peerAppData);
291
peerNetData.compact();
292
hs = res.getHandshakeStatus();
293
294
switch (res.getStatus()) {
295
case OK :
296
break;
297
case BUFFER_UNDERFLOW :
298
// maybe need to enlarge the peer network packet buffer.
299
int size = ssle.getSession().getPacketBufferSize();
300
if (size > peerNetData.capacity()) {
301
System.out.println("resize source buffer upto " +
302
size + " bytes for BUFFER_UNDERFLOW");
303
peerNetData = enlargeBuffer(peerNetData, size);
304
}
305
306
underflow = true;
307
break;
308
case BUFFER_OVERFLOW :
309
// maybe need to enlarge the peer application data buffer.
310
size = ssle.getSession().getApplicationBufferSize();
311
if (size > peerAppData.capacity()) {
312
System.out.println("resize destination buffer upto " +
313
size + " bytes for BUFFER_OVERFLOW");
314
peerAppData = enlargeBuffer(peerAppData, size);
315
}
316
break;
317
default : //CLOSED
318
throw new IOException("Received invalid" + res.getStatus() +
319
"during initial handshaking");
320
}
321
break;
322
323
case NEED_WRAP :
324
// empty the local network packet buffer.
325
localNetData.clear();
326
327
// generated local network packet.
328
res = ssle.wrap(localAppData, localNetData);
329
hs = res.getHandshakeStatus();
330
331
// checking status
332
switch (res.getStatus()) {
333
case OK :
334
localNetData.flip();
335
336
// send the network packet
337
while (localNetData.hasRemaining()) {
338
if (sc.write(localNetData) < 0) {
339
throw new IOException(
340
"Unable write to socket channel");
341
}
342
}
343
break;
344
345
case BUFFER_OVERFLOW :
346
// maybe need to enlarge the local network packet buffer.
347
int size = ssle.getSession().getPacketBufferSize();
348
if (size > localNetData.capacity()) {
349
System.out.println("resize destination buffer upto " +
350
size + " bytes for BUFFER_OVERFLOW");
351
localNetData = enlargeBuffer(localNetData, size);
352
}
353
break;
354
355
default : // BUFFER_UNDERFLOW or CLOSED :
356
throw new IOException("Received invalid" + res.getStatus() +
357
"during initial handshaking");
358
}
359
break;
360
361
case NEED_TASK :
362
Runnable runnable;
363
while ((runnable = ssle.getDelegatedTask()) != null) {
364
runnable.run();
365
}
366
hs = ssle.getHandshakeStatus();
367
break;
368
369
default : // FINISHED or NOT_HANDSHAKING
370
// do nothing
371
}
372
} while (hs != SSLEngineResult.HandshakeStatus.FINISHED &&
373
hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING);
374
}
375
376
private static ByteBuffer enlargeBuffer(ByteBuffer buffer, int size) {
377
ByteBuffer bb = ByteBuffer.allocate(size);
378
buffer.flip();
379
bb.put(buffer);
380
381
return bb;
382
}
383
384
/*
385
* Create an initialized SSLContext to use for this test.
386
*/
387
protected SSLEngine createSSLEngine(boolean mode) throws Exception {
388
389
SSLEngine ssle;
390
391
KeyStore ks = KeyStore.getInstance("JKS");
392
KeyStore ts = KeyStore.getInstance("JKS");
393
394
ks.load(new FileInputStream(keyFilename), passphrase);
395
ts.load(new FileInputStream(trustFilename), passphrase);
396
397
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
398
kmf.init(ks, passphrase);
399
400
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
401
tmf.init(ts);
402
403
SSLContext sslCtx = SSLContext.getInstance("TLS");
404
sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
405
406
ssle = sslCtx.createSSLEngine();
407
ssle.setUseClientMode(mode);
408
409
return ssle;
410
}
411
}
412
413