Solved

java ssl gateway timeout https

Posted on 2013-01-28
16
757 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
[Live Webinar] The Cloud Skills Gap

As Cloud technologies come of age, business leaders grapple with the impact it has on their team's skills and the gap associated with the use of a cloud platform.

Join experts from 451 Research and Concerto Cloud Services on July 27th where we will examine fact and fiction.

 
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
 
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

SharePoint Admin?

Enable Your Employees To Focus On The Core With Intuitive Onscreen Guidance That is With You At The Moment of Need.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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 Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collectio…
Viewers learn about the “while” loop and how to utilize it correctly in Java. Additionally, viewers begin exploring how to include conditional statements within a while loop and avoid an endless loop. Define While Loop: Basic Example: Explanatio…
The viewer will learn how to implement Singleton Design Pattern in Java.

615 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