hagrawal7777
hagrawal7777

Reputation: 14658

"openssl s_client -connect" exit after handshake

I am trying to test a SSL server and want to check whether a particular cipher is supported by the SSL server or not.

For that I am using following command = openssl s_client -connect google.com:443 -cipher RC4-SHA and invoking it from Java program as below and works pretty well, except for the fact that my Java program never exits because the openssl process started is still ON.

        Process process = Runtime.getRuntime().exec("openssl s_client -connect google.com:443");
        System.out.println("Waiting for process to terminate ...");
        process.waitFor();

        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = "";
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
        System.out.println("Exiting ...");

I see there is something like openssl s_client -connect google.com:443 -verify 0 but this is error return code and doesn't fetch the information I am looking for, however it do stops the openssl process.

Is there any way to exit the openssl connect once client-server handshake is completed?

Upvotes: 0

Views: 4485

Answers (1)

Anya Shenanigans
Anya Shenanigans

Reputation: 94584

Turns out that there's a problem with some native openssl client binaries on windows, which means that you end up with a non-terminating s_client, even if you close the standard input. Workrounds are terminating if you receive a known line from the output, or making a copy of the needed binaries from a cygwin installation to get the cygwin version of openssl to run without issue.

Note that the previous paragraph is for the Windows problem, the later paragraphs are perfectly usable for Linux/OSX.

Just before process.waitFor() we invoke process.getOutputStream().close() and it closes the input stream for openssl s_client; which triggers it's automatic termination logic. We close stderr as well, for good measure. The other thing is moving the output reading before the wait for process termination, in case the buffer gets filled at the OS level.

import java.io.*;

public class props {
    public static void main(String[] args) throws Exception {
        Process process = Runtime.getRuntime().exec("openssl s_client -connect google.com:443");
        process.getOutputStream().close();
        process.getErrorStream().close();

        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = "";
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
        System.out.println("Waiting for process to terminate ...");
        process.waitFor();
        System.out.println("Exiting ...");
    }
};

This is based on the statement under CONNECTED COMMANDS in the s_client man page, which states:

When used interactively (which means neither -quiet nor -ign_eof have been given), the session will be renegotiated if the line begins with an R, and if the line begins with a Q or if end of file is reached, the connection will be closed down.

Upvotes: 3

Related Questions