0

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?

hagrawal7777
  • 14,103
  • 5
  • 40
  • 70

1 Answers1

3

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.

Community
  • 1
  • 1
Anya Shenanigans
  • 91,618
  • 3
  • 107
  • 122
  • Thank you for your inputs .. Not working .. It closes the connection but because of timeout .. I got this in response `Timeout : 300 (sec)` .. – hagrawal7777 Sep 15 '15 at 13:31
  • Does my code as shown work on your system? I've tested it on OSX and Linux (openJDK 1.7.0_85) and both work as expected. You're sure you're placing the `process.getOutputStream().close()` *before* the `process.waitFor()`? – Anya Shenanigans Sep 15 '15 at 13:37
  • Oh yes sir .. 100% .. It didn't work .. Did you try without `process.getOutputStream().close()` ?? I think it will work then as well for you .. – hagrawal7777 Sep 15 '15 at 13:43
  • Actually, the other thing I would suggest is a slight refactor, moving the output reading *before* the `waitFor()` in order to prevent buffering related issues. But, not closing the stream will *always* trigger the timeout – Anya Shenanigans Sep 15 '15 at 13:44
  • I'm finding it very difficult to reproduce what you're seeing. I've [pastebinned](http://pastebin.com/XyucVkbk) *exactly* what I'm running and how rapidly it responds. Details like what you're running on would be helpful, but I've tried this on OSX, Linux *and* Windows (32&64bit VMs) and can't see how it would really have an effect having tested it across that many environments. I'm directly connected to the internet, and am not using any proxies for TLS traffic. Mind you… could google be rate limiting you because of the number of bad connections? – Anya Shenanigans Sep 15 '15 at 14:35
  • I have been trying on my Windows box with `OpenSSL 1.0.1j` version and I cannot exit without time out .. However when I tried same code in my Linux box with `OpenSSL 0.9.8e-fips-rhel5` then process was exited .. Could you please check your openssl version ?? If your's is also 0.9 then it may be possible that 0.9 exits and higher version don't .. – hagrawal7777 Sep 15 '15 at 14:56
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/89703/discussion-between-petesh-and-hagrawal). – Anya Shenanigans Sep 15 '15 at 15:01