Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing a Simple HTTPS Proxy Application with Java?

I'm writing a simple HTTPS proxy program with Java for educational purposes. My program listens on a port (say 7443) for incoming HTTPS requests from a browser (say Firefox), parses the request and forwards it to the desired destination (say https://www.comodo.com).

Firefox's proxy settings are set to use my port for SSL connections ( 127.0.0.1 : 7443 ).

My code is short and simple:

static // initializer
{
    System.setProperty("javax.net.ssl.keyStore", "MyKeyStore");
    System.setProperty("javax.net.ssl.keyStorePassword", "password");
}

SSLServerSocketFactory ssFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();

try {
    SSLServerSocket listener = (SSLServerSocket) ssFactory.createServerSocket(port, 64);
    listener.setUseClientMode(false);
    listener.setWantClientAuth(false);
    listener.setNeedClientAuth(false);

    SSLSocket connection = (SSLSocket) listener.accept();
    browser.startHandshake();  /*  <<==  Exception throws at this line  */

} catch (IOException ex) {
    ex.printStackTrace(System.err);
}

But I'm catching the following exception:

    javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?

The exception says that the connection could be plain-text, but only HTTPS connections from Firefox are set to use this port. I have logged what Firefox is sending to my application which is this:

CONNECT www.comodo.com:443 HTTP/1.1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:20.0) Gecko/20100101 Firefox/20.0
Proxy-Connection: keep-alive
Connection: keep-alive
Host: www.comodo.com

Firefox is talking palin-text, and I think CONNECT is a SOCKS command (I'm not sure though), where I haven't set anything in Firefox's SOCKS settings. Below is a screenshot of Firefox's proxy settings:

Firefox Proxy Settings

What am I missing here ?! What I need to do to make this work with Firefox or any other browser ?!

------------------------------------------------------------------------------

For those who think this is a duplicate of another question and that it has been answered in the other one I have to say: Yes, both questions have roots in a similar problem but the only answer in the cited question directs at using SSL Sockets which turned out to be misleading and resulted in this new question. So although they are aimed at a similar problem, this question shows a completely different and yet mislead path to go for solving the problem and so it could provide useful guidance for future persons facing such a problem.

like image 465
Seyed Mohammad Avatar asked May 03 '13 12:05

Seyed Mohammad


People also ask

Does Java use Http_proxy?

Java provides proxy handlers for HTTP, HTTPS, FTP, and SOCKS protocols. A proxy can be defined for each handler as a hostname and port number: http.


1 Answers

Get rid of all the SSL. Just process the incoming CONNECT command, make a plaintext connection to the upstream server, and then start copying bytes. The browser and the server will speak SSL but you don't need to at all.

like image 148
user207421 Avatar answered Sep 20 '22 07:09

user207421