|
import java.io.*;
|
|
import java.security.*;
|
|
import javax.net.ssl.*;
|
|
|
|
public class Server {
|
|
SSLServerSocketFactory ssf;
|
|
|
|
final static String CONTENT_LENGTH = "Content-Length: ";
|
|
|
|
public Server(SSLServerSocketFactory ssf) throws Exception {
|
|
this.ssf = ssf;
|
|
}
|
|
|
|
public void start(int port) throws Exception {
|
|
SSLServerSocket ss = (SSLServerSocket) ssf.createServerSocket(port);
|
|
try (SSLSocket sock = (SSLSocket) ss.accept()) {
|
|
System.out.println("Connected to " + sock.getPort());
|
|
try (BufferedReader r = new BufferedReader(new InputStreamReader(sock.getInputStream()))) {
|
|
try (BufferedWriter w = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()))) {
|
|
for (int i = 0; i < 2; i++) {
|
|
System.out.println("Handling request_" + i);
|
|
|
|
readRequest(r);
|
|
|
|
w.write("HTTP/1.1 200 OK\r\n");
|
|
w.write("Content-Length: 0\r\n");
|
|
w.write("\r\n");
|
|
|
|
SSLSession session = sock.getSession();
|
|
// This causes Java 17 to set the updateNST flag when using TLS 1.3:
|
|
// https://github.com/openjdk/jdk/blob/4cec141a90bc5d3b8ec17c024291d9c74a112cd4/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java#L1264
|
|
session.putValue("something", true);
|
|
System.out.println("updated session data");
|
|
|
|
// While encrypting the data, Java sees updateNST is set
|
|
// and sends a NewSessionTicket after the Application Data
|
|
// https://github.com/openjdk/jdk/blob/4cec141a90bc5d3b8ec17c024291d9c74a112cd4/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java#L1321-L1324
|
|
w.flush();
|
|
|
|
System.out.println("wrote response");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void readRequest(BufferedReader r) throws Exception {
|
|
int contentLength = 0;
|
|
|
|
// Request-Line
|
|
r.readLine();
|
|
|
|
String header = r.readLine();
|
|
while (header.length() > 0) {
|
|
//System.out.println(header);
|
|
if (header.startsWith(CONTENT_LENGTH)) {
|
|
contentLength = Integer.parseInt(header.substring(CONTENT_LENGTH.length()));
|
|
}
|
|
header = r.readLine();
|
|
}
|
|
|
|
int pos = 0;
|
|
char[] buf = new char[1024];
|
|
|
|
while (pos < contentLength) {
|
|
int n = r.read(buf, 0, Math.min(buf.length, contentLength));
|
|
if (n < 0) {
|
|
break;
|
|
}
|
|
|
|
pos += n;
|
|
contentLength -= n;
|
|
//System.out.println(buf);
|
|
}
|
|
|
|
while (r.ready()) {
|
|
int n = r.read(buf, 0, 1);
|
|
if (n < 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
System.out.println("read body");
|
|
}
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
KeyStore ks = KeyStore.getInstance("PKCS12");
|
|
char[] passphrase = "password".toCharArray();
|
|
try (InputStream in = new FileInputStream("./certs.p12")) {
|
|
ks.load(in, passphrase);
|
|
System.out.println("Loaded pkcs12");
|
|
}
|
|
|
|
KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX");
|
|
kmf.init(ks, passphrase);
|
|
|
|
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
|
|
tmf.init(ks);
|
|
|
|
SSLContext ctx = SSLContext.getInstance("TLSv1.3");
|
|
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
|
|
|
|
SSLServerSocketFactory ssf = ctx.getServerSocketFactory();
|
|
Server s = new Server(ssf);
|
|
s.start(8888);
|
|
}
|
|
}
|
|
|