Solved

java ssl gateway timeout https

Posted on 2013-01-28
16
655 Views
Last Modified: 2013-02-21
Dear experts,

I am trying to connect to a website through a proxy but i get a gateway timeout status 504
I am using this code:
public class SSLSocketClientWithTunneling {

    public static void main(String[] args) throws Exception {
	//new SSLSocketClientWithTunneling().doIt("www.google.com:443/HTTPS", 443);
new SSLSocketClientWithTunneling().doIt("https://necsapi.statnett.no:443/HTTPS", 443);
    }

    String tunnelHost;
    int tunnelPort;

    public void doIt(String host, int port) {
	try {

	    /*
	     * Let's setup the SSLContext first, as there's a lot of
	     * computations to be done.  If the socket were created
	     * before the SSLContext, the server/proxy might timeout
	     * waiting for the client to actually send something.
	     */
	    SSLSocketFactory factory =
		(SSLSocketFactory)SSLSocketFactory.getDefault();

	    /*
	     * Set up a socket to do tunneling through the proxy.
	     * Start it off as a regular socket, then layer SSL
	     * over the top of it.
	     */
       System.setProperty("https.proxyPort","8080");
       System.setProperty("https.proxyHost","myproxy");
       
       tunnelHost = System.getProperty("https.proxyHost");
       tunnelPort = Integer.getInteger("https.proxyPort").intValue();
       
      String keystoreFilename = System.getProperty("java.home")
        + "/lib/security/cacerts".replace('/', File.separatorChar);

    char[] password = "mypassword".toCharArray();
    String alias = "thecertificate";

    FileInputStream fIn = new FileInputStream(keystoreFilename);
    KeyStore keystore = KeyStore.getInstance("JKS");
    keystore.load(fIn, password);
    
	    Socket tunnel = new Socket(tunnelHost, tunnelPort);
	    doTunnelHandshake(tunnel, host, port);

	    /*
	     * Ok, let's overlay the tunnel socket with SSL.
	     */
	    SSLSocket socket =
		(SSLSocket)factory.createSocket(tunnel, host, port, true);

	    /*
	     * register a callback for handshaking completion event
	     */
	    socket.addHandshakeCompletedListener(
		new HandshakeCompletedListener() {
		    public void handshakeCompleted(
			    HandshakeCompletedEvent event) {
			System.out.println("Handshake finished!");
			System.out.println(
			    "\t CipherSuite:" + event.getCipherSuite());
			System.out.println(
			    "\t SessionId " + event.getSession());
			System.out.println(
			    "\t PeerHost " + event.getSession().getPeerHost());
		    }
		}
	    );

	    /*
	     * send http request
	     *
	     * See SSLSocketClient.java for more information about why
	     * there is a forced handshake here when using PrintWriters.
	     */
	    socket.startHandshake();

	    PrintWriter out = new PrintWriter(
				  new BufferedWriter(
				  new OutputStreamWriter(
     				  socket.getOutputStream())));

	    out.println("GET / HTTP/1.0");
	    out.println();
	    out.flush();

	    /*
	     * Make sure there were no surprises
	     */
	    if (out.checkError())
		System.out.println(
		    "SSLSocketClient:  java.io.PrintWriter error");

	    /* read response */
	    BufferedReader in = new BufferedReader(
				    new InputStreamReader(
				    socket.getInputStream()));

	    String inputLine;

	    while ((inputLine = in.readLine()) != null)
		System.out.println(inputLine);

	    in.close();
	    out.close();
	    socket.close();
	    tunnel.close();
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }

    /*
     * Tell our tunnel where we want to CONNECT, and look for the
     * right reply.  Throw IOException if anything goes wrong.
     */
    private void doTunnelHandshake(Socket tunnel, String host, int port)
    throws IOException
    {
	OutputStream out = tunnel.getOutputStream();
	String msg = "CONNECT " + host + ":" + port + " HTTP/1.0\n"
		     + "User-Agent: "
		     + sun.net.www.protocol.http.HttpURLConnection.userAgent
		     + "\r\n\r\n";
	byte b[];
	try {
	    /*
	     * We really do want ASCII7 -- the http protocol doesn't change
	     * with locale.
	     */
	    b = msg.getBytes("ASCII7");
	} catch (UnsupportedEncodingException ignored) {
	    /*
	     * If ASCII7 isn't there, something serious is wrong, but
	     * Paranoia Is Good (tm)
	     */
	    b = msg.getBytes();
	}
	out.write(b);
	out.flush();

	/*
	 * We need to store the reply so we can create a detailed
	 * error message to the user.
	 */
	byte		reply[] = new byte[200];
	int		replyLen = 0;
	int		newlinesSeen = 0;
	boolean		headerDone = false;	/* Done on first newline */

	InputStream	in = tunnel.getInputStream();
	boolean		error = false;

	while (newlinesSeen < 2) {
	    int i = in.read();
	    if (i < 0) {
		throw new IOException("Unexpected EOF from proxy");
	    }
	    if (i == '\n') {
		headerDone = true;
		++newlinesSeen;
	    } else if (i != '\r') {
		newlinesSeen = 0;
		if (!headerDone && replyLen < reply.length) {
		    reply[replyLen++] = (byte) i;
		}
	    }
	}

	/*
	 * Converting the byte array to a string is slightly wasteful
	 * in the case where the connection was successful, but it's
	 * insignificant compared to the network overhead.
	 */
	String replyStr;
	try {
	    replyStr = new String(reply, 0, replyLen, "ASCII7");
	} catch (UnsupportedEncodingException ignored) {
	    replyStr = new String(reply, 0, replyLen);
	}

	/* We asked for HTTP/1.0, so we should get that back */
	if (!replyStr.startsWith("HTTP/1.0 200")) {
	    throw new IOException("Unable to tunnel through "
		    + tunnelHost + ":" + tunnelPort 
		    + ".  Proxy returns \"" + replyStr + "\"");
	}

	/* tunneling Handshake was successful! */
    }
}

Open in new window


This code works if i do:       new SSLSocketClientWithTunneling().doIt("www.google.com:443/HTTPS", 443);
instead of:
new SSLSocketClientWithTunneling().doIt("https://necsapi.statnett.no:443/HTTPS", 443);

I hope someone can help me!

KInd regards,

Mark
0
Comment
Question by:MarkVrenken
  • 8
  • 8
16 Comments
 
LVL 35

Expert Comment

by:girionis
ID: 38835064
Can you access the https://necsapi.statnett.no from a browser?
0
 
LVL 1

Author Comment

by:MarkVrenken
ID: 38835213
Yes i can, I then have to select the certificate. I think I got a little further but now i get
java.io.IOException: Unable to tunnel through "myProxy" Proxy returns "HTTP/1.0 403 Forbidden"
0
 
LVL 35

Expert Comment

by:girionis
ID: 38835580
When you read the keystore, are you sure you read the correct one?
0
 
LVL 1

Author Comment

by:MarkVrenken
ID: 38835601
Yes. I added it to cacerts, and get the right certificate.
0
 
LVL 35

Expert Comment

by:girionis
ID: 38838575
Do you send the correct username/password?
0
 
LVL 1

Author Comment

by:MarkVrenken
ID: 38838946
I fixed the 403 error. It was because I set my forward to the proxy as
https://necsapi.statnett.no:443/HTTPS" but this was already added in my code, stupid me!

so the proxy forwarded this tunnel://https://necsapi.statnett.no:443/HTTPS/1.0:443
so instead I used this necsapi.statnett.no which then is forwarded as tunnel://necsapi.statnett.no:443

but now i get the following error which your questions were leading to. namely i get this error:PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

I don't know how I should edit my code to add the right certificate. I know I added the right certificate to my cacerts. but I'm not sure how to access this in Java and present it to the server
0
 
LVL 35

Expert Comment

by:girionis
ID: 38838985
0
 
LVL 1

Author Comment

by:MarkVrenken
ID: 38839194
Thank you this solved the next problem. Now I can access the site but I get the websites 403 page. (I print the page this is a part of the page):

</head>
       PeerHost necsapi.statnett.no
<body>
<div id="header"><h1>Error</h1></div>
<div id="content">
 <div class="content-container"><fieldset>
  <h2>Forbidden: Access is denied.</h2>
  <h3>You do not have permission to view this directory or page using the credentials that you supplied.</h3>

 </fieldset></div>
</div>
</body>
</html>

So something is wrong with me presenting the server certificate? I don't know how I should approach this problem. I have received a certificate (.pfx) from the server people which I installed for my browser. So when I browse to the page, I get prompted to select the certificate and I can view the content. However through java I have to do this in another way. So my question now is: How do I present the certificate to the server so that I get "logged in"?

Thanks for your help I appreciate it!
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 35

Expert Comment

by:girionis
ID: 38839263
It doesn't have to do with the certificate, it looks like a problem with the site, it's probably password protected. You need to authenticate yourself with a user/pass.
0
 
LVL 1

Author Comment

by:MarkVrenken
ID: 38839282
Okay, but why can i access the site through my browser then? On the browser I only have to select the certificate.
0
 
LVL 35

Expert Comment

by:girionis
ID: 38839291
Maybe the browser is using cookies to identify you. Try something else. Delete all the cookies for this site and load it again from the browser.
0
 
LVL 1

Author Comment

by:MarkVrenken
ID: 38839308
I have never had to insert any credentials in the browser, just the certificate selection
0
 
LVL 35

Expert Comment

by:girionis
ID: 38839321
Then the only reasonable explanation is that the browser redirects you to another page. Since you cannot follow the redirection from your application you get the forbidden error message. Do something else. If you use firefox install Live HTTP headers and have a look at the request. You will see if it redirects you to another page or not.
0
 
LVL 1

Author Comment

by:MarkVrenken
ID: 38839448
I didn't have firefox, I installed it but I get the forbidden access denied for the site(403).
This is not in chrome nor IE, so that's strange....
0
 
LVL 1

Author Comment

by:MarkVrenken
ID: 38839575
HTTP request status: 200 (OK)
Name      Value
Date      Thu, 31 Jan 2013 14:26:22 GMT
X-Content-Type-Options      nosniff
Server      Microsoft-IIS/7.5
X-AspNet-Version      4.0.30319
X-Powered-By      ASP.NET
Content-Type      application/xml;charset=iso-8859-1
Cache-Control      no-cache
DataServiceVersion      1.0;
Content-Length      661

this is what I get in chrome http headers if i have selected the certificate

I think you are right about the redirection by the way..
because the URL i enter is :https://necsapi.statnett.no
and the URL after selecting the certificate is: https://necsapi.statnett.no/odata.svc/
0
 
LVL 35

Accepted Solution

by:
girionis earned 500 total points
ID: 38840233
I am getting a forbidden error with ff, ie and chrome.
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now