Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/net/ssl/ServerName/SSLEngineExplorerMatchedSNI.java
41152 views
1
/*
2
* Copyright (c) 2012, 2021, 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
// SunJSSE does not support dynamic system properties, no way to re-use
26
// system properties in samevm/agentvm mode.
27
//
28
29
/*
30
* @test
31
* @bug 7068321
32
* @summary Support TLS Server Name Indication (SNI) Extension in JSSE Server
33
* @library ../SSLEngine ../templates
34
* @build SSLEngineService SSLCapabilities SSLExplorer
35
* @run main/othervm SSLEngineExplorerMatchedSNI www.example.com
36
* www\.example\.com
37
* @run main/othervm SSLEngineExplorerMatchedSNI www.example.com
38
* www\.example\.(com|org)
39
* @run main/othervm SSLEngineExplorerMatchedSNI example.com
40
* (.*\.)*example\.(com|org)
41
* @run main/othervm SSLEngineExplorerMatchedSNI www.example.com
42
* (.*\.)*example\.(com|org)
43
* @run main/othervm SSLEngineExplorerMatchedSNI www.us.example.com
44
* (.*\.)*example\.(com|org)
45
*/
46
47
import javax.net.ssl.*;
48
import java.nio.*;
49
import java.net.*;
50
import java.util.*;
51
import java.nio.channels.*;
52
53
public class SSLEngineExplorerMatchedSNI extends SSLEngineService {
54
55
/*
56
* =============================================================
57
* Set the various variables needed for the tests, then
58
* specify what tests to run on each side.
59
*/
60
61
/*
62
* Should we run the client or server in a separate thread?
63
* Both sides can throw exceptions, but do you have a preference
64
* as to which side should be the main thread.
65
*/
66
static boolean separateServerThread = false;
67
68
// Is the server ready to serve?
69
volatile static boolean serverReady = false;
70
71
/*
72
* Turn on SSL debugging?
73
*/
74
static boolean debug = true;
75
76
/*
77
* Define the server side of the test.
78
*
79
* If the server prematurely exits, serverReady will be set to true
80
* to avoid infinite hangs.
81
*/
82
void doServerSide() throws Exception {
83
84
// create SSLEngine.
85
SSLEngine ssle = createSSLEngine(false);
86
87
// Create a server socket channel.
88
InetSocketAddress isa =
89
new InetSocketAddress(InetAddress.getLocalHost(), serverPort);
90
ServerSocketChannel ssc = ServerSocketChannel.open();
91
ssc.socket().bind(isa);
92
serverPort = ssc.socket().getLocalPort();
93
94
// Signal Client, we're ready for his connect.
95
serverReady = true;
96
97
// Accept a socket channel.
98
SocketChannel sc = ssc.accept();
99
100
// Complete connection.
101
while (!sc.finishConnect()) {
102
Thread.sleep(50);
103
// waiting for the connection completed.
104
}
105
106
ByteBuffer buffer = ByteBuffer.allocate(0xFF);
107
int position = 0;
108
SSLCapabilities capabilities = null;
109
110
// Read the header of TLS record
111
buffer.limit(SSLExplorer.RECORD_HEADER_SIZE);
112
while (position < SSLExplorer.RECORD_HEADER_SIZE) {
113
int n = sc.read(buffer);
114
if (n < 0) {
115
throw new Exception("unexpected end of stream!");
116
}
117
position += n;
118
}
119
buffer.flip();
120
121
int recordLength = SSLExplorer.getRequiredSize(buffer);
122
if (buffer.capacity() < recordLength) {
123
ByteBuffer oldBuffer = buffer;
124
buffer = ByteBuffer.allocate(recordLength);
125
buffer.put(oldBuffer);
126
}
127
128
buffer.position(SSLExplorer.RECORD_HEADER_SIZE);
129
buffer.limit(buffer.capacity());
130
while (position < recordLength) {
131
int n = sc.read(buffer);
132
if (n < 0) {
133
throw new Exception("unexpected end of stream!");
134
}
135
position += n;
136
}
137
buffer.flip();
138
139
capabilities = SSLExplorer.explore(buffer);
140
if (capabilities != null) {
141
System.out.println("Record version: " +
142
capabilities.getRecordVersion());
143
System.out.println("Hello version: " +
144
capabilities.getHelloVersion());
145
}
146
147
// enable server name indication checking
148
SNIMatcher matcher = SNIHostName.createSNIMatcher(
149
serverAcceptableHostname);
150
Collection<SNIMatcher> matchers = new ArrayList<>(1);
151
matchers.add(matcher);
152
SSLParameters params = ssle.getSSLParameters();
153
params.setSNIMatchers(matchers);
154
ssle.setSSLParameters(params);
155
156
// handshaking
157
handshaking(ssle, sc, buffer);
158
159
// receive application data
160
receive(ssle, sc);
161
162
// send out application data
163
deliver(ssle, sc);
164
165
// check server name indication
166
ExtendedSSLSession session = (ExtendedSSLSession)ssle.getSession();
167
checkCapabilities(capabilities, session);
168
169
// close the socket channel.
170
sc.close();
171
ssc.close();
172
}
173
174
/*
175
* Define the client side of the test.
176
*
177
* If the server prematurely exits, serverReady will be set to true
178
* to avoid infinite hangs.
179
*/
180
void doClientSide() throws Exception {
181
// create SSLEngine.
182
SSLEngine ssle = createSSLEngine(true);
183
184
/*
185
* Wait for server to get started.
186
*/
187
while (!serverReady) {
188
Thread.sleep(50);
189
}
190
191
// Create a non-blocking socket channel.
192
SocketChannel sc = SocketChannel.open();
193
sc.configureBlocking(false);
194
InetSocketAddress isa =
195
new InetSocketAddress(InetAddress.getLocalHost(), serverPort);
196
sc.connect(isa);
197
198
// Complete connection.
199
while (!sc.finishConnect() ) {
200
Thread.sleep(50);
201
// waiting for the connection completed.
202
}
203
204
SNIHostName serverName = new SNIHostName(clientRequestedHostname);
205
List<SNIServerName> serverNames = new ArrayList<>(1);
206
serverNames.add(serverName);
207
SSLParameters params = ssle.getSSLParameters();
208
params.setServerNames(serverNames);
209
ssle.setSSLParameters(params);
210
211
// handshaking
212
handshaking(ssle, sc, null);
213
214
// send out application data
215
deliver(ssle, sc);
216
217
// receive application data
218
receive(ssle, sc);
219
220
// check server name indication
221
ExtendedSSLSession session = (ExtendedSSLSession)ssle.getSession();
222
checkSNIInSession(session);
223
224
// close the socket channel.
225
sc.close();
226
}
227
228
void checkCapabilities(SSLCapabilities capabilities,
229
ExtendedSSLSession session) throws Exception {
230
List<SNIServerName> sessionSNI = session.getRequestedServerNames();
231
if (!sessionSNI.equals(capabilities.getServerNames())) {
232
for (SNIServerName sni : sessionSNI) {
233
System.out.println("SNI in session is " + sni);
234
}
235
236
List<SNIServerName> capaSNI = capabilities.getServerNames();
237
for (SNIServerName sni : capaSNI) {
238
System.out.println("SNI in session is " + sni);
239
}
240
241
throw new Exception(
242
"server name indication does not match capabilities");
243
}
244
245
checkSNIInSession(session);
246
}
247
248
void checkSNIInSession(ExtendedSSLSession session) throws Exception {
249
List<SNIServerName> sessionSNI = session.getRequestedServerNames();
250
if (sessionSNI.isEmpty()) {
251
throw new Exception(
252
"unexpected empty request server name indication");
253
}
254
255
if (sessionSNI.size() != 1) {
256
throw new Exception(
257
"unexpected request server name indication");
258
}
259
260
SNIServerName serverName = sessionSNI.get(0);
261
if (!(serverName instanceof SNIHostName)) {
262
throw new Exception(
263
"unexpected instance of request server name indication");
264
}
265
266
String hostname = ((SNIHostName)serverName).getAsciiName();
267
if (!clientRequestedHostname.equalsIgnoreCase(hostname)) {
268
throw new Exception(
269
"unexpected request server name indication value");
270
}
271
}
272
273
private static String clientRequestedHostname;
274
private static String serverAcceptableHostname;
275
276
private static void parseArguments(String[] args) {
277
clientRequestedHostname = args[0];
278
serverAcceptableHostname = args[1];
279
}
280
281
/*
282
* =============================================================
283
* The remainder is just support stuff
284
*/
285
volatile Exception serverException = null;
286
volatile Exception clientException = null;
287
288
// use any free port by default
289
volatile int serverPort = 0;
290
291
public static void main(String args[]) throws Exception {
292
if (debug)
293
System.setProperty("javax.net.debug", "all");
294
295
/*
296
* Get the customized arguments.
297
*/
298
parseArguments(args);
299
300
new SSLEngineExplorerMatchedSNI();
301
}
302
303
Thread clientThread = null;
304
Thread serverThread = null;
305
306
/*
307
* Primary constructor, used to drive remainder of the test.
308
*
309
* Fork off the other side, then do your work.
310
*/
311
SSLEngineExplorerMatchedSNI() throws Exception {
312
super("../etc");
313
314
if (separateServerThread) {
315
startServer(true);
316
startClient(false);
317
} else {
318
startClient(true);
319
startServer(false);
320
}
321
322
/*
323
* Wait for other side to close down.
324
*/
325
if (separateServerThread) {
326
serverThread.join();
327
} else {
328
clientThread.join();
329
}
330
331
/*
332
* When we get here, the test is pretty much over.
333
*
334
* If the main thread excepted, that propagates back
335
* immediately. If the other thread threw an exception, we
336
* should report back.
337
*/
338
if (serverException != null) {
339
System.out.print("Server Exception:");
340
throw serverException;
341
}
342
if (clientException != null) {
343
System.out.print("Client Exception:");
344
throw clientException;
345
}
346
}
347
348
void startServer(boolean newThread) throws Exception {
349
if (newThread) {
350
serverThread = new Thread() {
351
public void run() {
352
try {
353
doServerSide();
354
} catch (Exception e) {
355
/*
356
* Our server thread just died.
357
*
358
* Release the client, if not active already...
359
*/
360
System.err.println("Server died...");
361
System.err.println(e);
362
serverReady = true;
363
serverException = e;
364
}
365
}
366
};
367
serverThread.start();
368
} else {
369
doServerSide();
370
}
371
}
372
373
void startClient(boolean newThread) throws Exception {
374
if (newThread) {
375
clientThread = new Thread() {
376
public void run() {
377
try {
378
doClientSide();
379
} catch (Exception e) {
380
/*
381
* Our client thread just died.
382
*/
383
System.err.println("Client died...");
384
clientException = e;
385
}
386
}
387
};
388
clientThread.start();
389
} else {
390
doClientSide();
391
}
392
}
393
}
394
395