2

trying to implement TLS 1.2 vs TLS 1.3 handshake measurement with the focus on session resumption.

TLS 1.2 is working perfectly fine, with ID and Ticket resumption, but when changing to TLS 1.3 it doesn't.

Unfortunately the wireshark data is encrypted, but java states the following:

javax.net.ssl|DEBUG|17|Thread-3|2021-01-09 20:36:54.491 CET|PreSharedKeyExtension.java:634|No session to resume.
javax.net.ssl|DEBUG|17|Thread-3|2021-01-09 20:36:54.491 CET|SSLExtensions.java:260|Ignore, context unavailable extension: pre_shared_key

We're not trying to implement 0RTT resumption, but work with SessionTickets. The Client does not send a PresharedKey to the server.

javax.net.ssl|DEBUG|16|Thread-2|2021-01-09 20:36:54.564 CET|PreSharedKeyExtension.java:807|Handling pre_shared_key absence.

Code (Client):

public class Client implements Runnable {
    private String version;
    private int count;
    private final int PORT = 8084;
    private String[] cipher_suites;
    private boolean sessionResumption;

    private SSLServerSocket serverSocket;

    public Client(String tlsVersion,int count, boolean resumeSession) {
        this.version = tlsVersion;
        this.count = count;
        this.sessionResumption = resumeSession;
    }


    private SSLContext getContext() {
        SSLContext context = null;
        try {
            InputStream stream = this.getClass().getResourceAsStream("/sslclienttrust");
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            char[] trustStorePassword = "]3!z2Tb?@EHu%d}Q".toCharArray();
            trustStore.load(stream, trustStorePassword);
            context = SSLContext.getInstance(version);

            TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            factory.init(trustStore);
            TrustManager[] managers = factory.getTrustManagers();
            context.init(null, managers, null);
        } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | KeyManagementException e) {
            e.printStackTrace();

        }
        return context;
    }

    public void startHandshake(SSLSocketFactory sf) throws IOException {
        long startTime = -1;
        try (SSLSocket socket = createSocket(sf)) {
            //InputStream is = new BufferedInputStream(socket.getInputStream());
            startTime = System.currentTimeMillis();
            socket.startHandshake();
        }
        long endTime = System.currentTimeMillis();
        long timeElapsed = endTime - startTime;
        System.out.println("Time Handshake " + timeElapsed );

    }

    private SSLSocket createSocket(SSLSocketFactory sf) throws IOException {
        SSLSocket s = (SSLSocket) sf.createSocket("localhost", PORT);
        s.setEnabledProtocols(new String[]{version});
        //s.setEnabledCipherSuites(new String[]{"TLS_RSA_WITH_AES_128_CBC_SHA256"});
        return s;
    }

    @Override
    public void run() {
        startTime = System.currentTimeMillis();
        SSLSocketFactory s = null;
        if(sessionResumption){
            s = getContext().getSocketFactory();
        }
        while(count>0){

            try {
                if(!sessionResumption){
                    s = getContext().getSocketFactory();
                }
                startHandshake(s);
                count--;
                Thread.sleep(1);
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
                count = 0;
            }

        }

    }

Server :

public class Server implements Runnable {
    private String version;
    private boolean keepAlive;
    private final int PORT = 8084;
    private String[] cipher_suites;

    private SSLServerSocket serverSocket;

    public Server(String tlsVersion, boolean keepAlive) {
        this.version = tlsVersion;
        this.keepAlive = keepAlive;
    }

    private SSLContext getContext() {
        SSLContext context = null;
        try {



            InputStream stream = this.getClass().getResourceAsStream("/sslserverkeys");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(stream, "7x*;^C(HU~5}@P?h".toCharArray());

            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(keyStore, "7x*;^C(HU~5}@P?h".toCharArray());
            KeyManager[] km = keyManagerFactory.getKeyManagers();

            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            TrustManager[] tm = trustManagerFactory.getTrustManagers();

            context = SSLContext.getInstance(version);
            context.init(km, tm, null);
        } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | KeyManagementException | UnrecoverableKeyException e) {
            e.printStackTrace();

        }
        return context;
    }

    public void acceptHandshake() throws IOException {
        //verbindung
        try (SSLSocket socket = (SSLSocket) serverSocket.accept()) {
            socket.setEnabledProtocols(new String[]{version});
            socket.startHandshake();


        }

    }
    public void configure(){
        SSLServerSocketFactory factory = getContext().getServerSocketFactory();
        try {
            serverSocket = ((SSLServerSocket) factory.createServerSocket(this.PORT));
            //config
            serverSocket.setEnabledProtocols(new String[]{version});
            serverSocket.setEnabledCipherSuites(serverSocket.getSupportedCipherSuites());

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        configure();
            try {
                while(keepAlive){
                    acceptHandshake();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
    }
}

Thanks in advance :)

Danzon2504
  • 53
  • 1
  • 10

1 Answers1

0

Update: This seems not to be implemented (yet).

"Resumption using PSK only: The initial implementation allows resumption by authenticating with the PSK followed by a DHE exchange to set up the master secret. PSK-only mode is more efficient, but it has weaker security w.r.t. forward and backward secrecy."

https://bugs.openjdk.java.net/browse/JDK-8049402

Danzon2504
  • 53
  • 1
  • 10