Skip to content

Commit fdc8f4a

Browse files
committed
backport e6ebefaa404daa4160bdc1c5d9c954c040e2c0c2
1 parent efa1f8e commit fdc8f4a

File tree

2 files changed

+261
-278
lines changed

2 files changed

+261
-278
lines changed

test/jdk/sun/security/ssl/SSLSessionImpl/ResumeChecksClient.java

Lines changed: 105 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
2323

2424
/*
2525
* @test
26-
* @bug 8206929 8212885
26+
* @bug 8206929 8212885 8333857
2727
* @summary ensure that client only resumes a session if certain properties
2828
* of the session are compatible with the new connection
2929
* @library /javax/net/ssl/templates
@@ -47,6 +47,9 @@
4747
import java.security.*;
4848
import java.net.*;
4949
import java.util.*;
50+
import java.util.concurrent.CountDownLatch;
51+
import java.util.concurrent.ExecutorService;
52+
import java.util.concurrent.Executors;
5053

5154
public class ResumeChecksClient extends SSLContextTemplate {
5255
enum TestMode {
@@ -56,49 +59,60 @@ enum TestMode {
5659
CIPHER_SUITE,
5760
SIGNATURE_SCHEME
5861
}
62+
static TestMode testMode;
5963

6064
public static void main(String[] args) throws Exception {
61-
new ResumeChecksClient(TestMode.valueOf(args[0])).run();
65+
testMode = TestMode.valueOf(args[0]);
66+
new ResumeChecksClient().test();
6267
}
6368

64-
private final TestMode testMode;
65-
public ResumeChecksClient(TestMode mode) {
66-
this.testMode = mode;
67-
}
68-
69-
private void run() throws Exception {
70-
Server server = startServer();
71-
server.signal();
69+
private void test() throws Exception {
70+
Server server = new Server();
7271
SSLContext sslContext = createClientSSLContext();
73-
while (!server.started) {
74-
Thread.yield();
75-
}
76-
SSLSession firstSession = connect(sslContext, server.port, testMode, false);
72+
HexFormat hex = HexFormat.of();
73+
long firstStartTime = System.currentTimeMillis();
74+
SSLSession firstSession = connect(sslContext, server.port, true);
75+
System.err.println("firstStartTime = " + firstStartTime);
76+
System.err.println("firstId = " + hex.formatHex(firstSession.getId()));
77+
System.err.println("firstSession.getCreationTime() = " +
78+
firstSession.getCreationTime());
7779

78-
server.signal();
7980
long secondStartTime = System.currentTimeMillis();
80-
Thread.sleep(10);
81-
SSLSession secondSession = connect(sslContext, server.port, testMode, true);
82-
83-
server.go = false;
84-
server.signal();
81+
SSLSession secondSession = connect(sslContext, server.port, false);
82+
System.err.println("secondStartTime = " + secondStartTime);
83+
// Note: Ids will never match with TLS 1.3 due to spec
84+
System.err.println("secondId = " + hex.formatHex(secondSession.getId()));
85+
System.err.println("secondSession.getCreationTime() = " +
86+
secondSession.getCreationTime());
8587

8688
switch (testMode) {
8789
case BASIC:
8890
// fail if session is not resumed
89-
checkResumedSession(firstSession, secondSession);
91+
try {
92+
checkResumedSession(firstSession, secondSession);
93+
} catch (Exception e) {
94+
throw new AssertionError("secondSession did not resume: FAIL",
95+
e);
96+
}
97+
System.out.println("secondSession used resumption: PASS");
9098
break;
9199
case VERSION_2_TO_3:
92100
case VERSION_3_TO_2:
93101
case CIPHER_SUITE:
94102
case SIGNATURE_SCHEME:
95103
// fail if a new session is not created
96-
if (secondSession.getCreationTime() <= secondStartTime) {
97-
throw new RuntimeException("Existing session was used");
104+
try {
105+
checkResumedSession(firstSession, secondSession);
106+
System.err.println("firstSession = " + firstSession);
107+
System.err.println("secondSession = " + secondSession);
108+
throw new AssertionError("Second connection should not " +
109+
"have resumed first session: FAIL");
110+
} catch (Exception e) {
111+
System.out.println("secondSession didn't use resumption: PASS");
98112
}
99113
break;
100114
default:
101-
throw new RuntimeException("unknown mode: " + testMode);
115+
throw new AssertionError("unknown mode: " + testMode);
102116
}
103117
}
104118

@@ -134,51 +148,29 @@ public boolean permits(Set<CryptoPrimitive> primitives,
134148
}
135149

136150
private static SSLSession connect(SSLContext sslContext, int port,
137-
TestMode mode, boolean second) {
151+
boolean first) {
138152

139153
try {
140154
SSLSocket sock = (SSLSocket)
141155
sslContext.getSocketFactory().createSocket();
142156
SSLParameters params = sock.getSSLParameters();
143157

144-
switch (mode) {
145-
case BASIC:
146-
// do nothing to ensure resumption works
147-
break;
148-
case VERSION_2_TO_3:
149-
if (second) {
150-
params.setProtocols(new String[] {"TLSv1.3"});
151-
} else {
152-
params.setProtocols(new String[] {"TLSv1.2"});
153-
}
154-
break;
155-
case VERSION_3_TO_2:
156-
if (second) {
157-
params.setProtocols(new String[] {"TLSv1.2"});
158-
} else {
159-
params.setProtocols(new String[] {"TLSv1.3"});
160-
}
161-
break;
162-
case CIPHER_SUITE:
163-
if (second) {
164-
params.setCipherSuites(
165-
new String[] {"TLS_AES_256_GCM_SHA384"});
166-
} else {
167-
params.setCipherSuites(
168-
new String[] {"TLS_AES_128_GCM_SHA256"});
169-
}
170-
break;
171-
case SIGNATURE_SCHEME:
172-
AlgorithmConstraints constraints =
173-
params.getAlgorithmConstraints();
174-
if (second) {
175-
params.setAlgorithmConstraints(new NoSig("ecdsa"));
176-
} else {
177-
params.setAlgorithmConstraints(new NoSig("rsa"));
178-
}
179-
break;
180-
default:
181-
throw new RuntimeException("unknown mode: " + mode);
158+
switch (testMode) {
159+
case BASIC -> {} // do nothing
160+
case VERSION_2_TO_3 -> params.setProtocols(new String[]{
161+
first ? "TLSv1.2" : "TLSv1.3"});
162+
case VERSION_3_TO_2 -> params.setProtocols(new String[]{
163+
first ? "TLSv1.3" : "TLSv1.2"});
164+
case CIPHER_SUITE -> params.setCipherSuites(
165+
new String[]{
166+
first ? "TLS_AES_128_GCM_SHA256" :
167+
"TLS_AES_256_GCM_SHA384"});
168+
case SIGNATURE_SCHEME ->
169+
params.setAlgorithmConstraints(new NoSig(
170+
first ? "rsa" : "ecdsa"));
171+
default ->
172+
throw new AssertionError("unknown mode: " +
173+
testMode);
182174
}
183175
sock.setSSLParameters(params);
184176
sock.connect(new InetSocketAddress("localhost", port));
@@ -195,7 +187,7 @@ private static SSLSession connect(SSLContext sslContext, int port,
195187
return result;
196188
} catch (Exception ex) {
197189
// unexpected exception
198-
throw new RuntimeException(ex);
190+
throw new AssertionError(ex);
199191
}
200192
}
201193

@@ -274,65 +266,63 @@ private static void checkResumedSession(SSLSession initSession,
274266
}
275267
}
276268

277-
private static Server startServer() {
278-
Server server = new Server();
279-
new Thread(server).start();
280-
return server;
281-
}
282-
283-
private static class Server extends SSLContextTemplate implements Runnable {
284-
285-
public volatile boolean go = true;
286-
private boolean signal = false;
287-
public volatile int port = 0;
288-
public volatile boolean started = false;
269+
private static class Server extends SSLContextTemplate {
270+
public int port;
271+
private final SSLServerSocket ssock;
272+
ExecutorService threadPool = Executors.newFixedThreadPool(1);
273+
CountDownLatch serverLatch = new CountDownLatch(1);
289274

290-
private synchronized void waitForSignal() {
291-
while (!signal) {
292-
try {
293-
wait();
294-
} catch (InterruptedException ex) {
295-
// do nothing
296-
}
297-
}
298-
signal = false;
299-
}
300-
public synchronized void signal() {
301-
signal = true;
302-
notify();
303-
}
304-
305-
@Override
306-
public void run() {
275+
Server() {
307276
try {
308-
309277
SSLContext sc = createServerSSLContext();
310278
ServerSocketFactory fac = sc.getServerSocketFactory();
311-
SSLServerSocket ssock = (SSLServerSocket)
312-
fac.createServerSocket(0);
313-
this.port = ssock.getLocalPort();
279+
ssock = (SSLServerSocket) fac.createServerSocket(0);
280+
port = ssock.getLocalPort();
314281

315-
waitForSignal();
316-
started = true;
317-
while (go) {
282+
// Thread to allow multiple clients to connect
283+
new Thread(() -> {
318284
try {
319-
System.out.println("Waiting for connection");
320-
Socket sock = ssock.accept();
321-
BufferedReader reader = new BufferedReader(
322-
new InputStreamReader(sock.getInputStream()));
323-
String line = reader.readLine();
324-
System.out.println("server read: " + line);
325-
PrintWriter out = new PrintWriter(
326-
new OutputStreamWriter(sock.getOutputStream()));
327-
out.println(line);
328-
out.flush();
329-
waitForSignal();
285+
System.err.println("Server starting to accept");
286+
serverLatch.countDown();
287+
do {
288+
threadPool.submit(
289+
new ServerThread((SSLSocket) ssock.accept()));
290+
} while (true);
330291
} catch (Exception ex) {
331-
ex.printStackTrace();
292+
throw new AssertionError("Server Down", ex);
293+
} finally {
294+
threadPool.close();
332295
}
296+
}).start();
297+
298+
} catch (Exception e) {
299+
throw new AssertionError(e);
300+
}
301+
}
302+
303+
static class ServerThread extends Thread {
304+
SSLSocket sock;
305+
306+
ServerThread(SSLSocket s) {
307+
this.sock = s;
308+
System.err.println("(Server) client connection on port " +
309+
sock.getPort());
310+
}
311+
312+
public void run() {
313+
try {
314+
BufferedReader reader = new BufferedReader(
315+
new InputStreamReader(sock.getInputStream()));
316+
String line = reader.readLine();
317+
System.out.println("server read: " + line);
318+
PrintWriter out = new PrintWriter(
319+
new OutputStreamWriter(sock.getOutputStream()));
320+
out.println(line);
321+
out.flush();
322+
out.close();
323+
} catch (Exception e) {
324+
throw new AssertionError("Server thread error", e);
333325
}
334-
} catch (Exception ex) {
335-
throw new RuntimeException(ex);
336326
}
337327
}
338328
}

0 commit comments

Comments
 (0)