9

Using the Java URL class, I can connect to an external HTTPS server (such as our production site), but using a local URL I get following exception.

"SunCertPathBuilderException: unable to find valid certification path to requested target".

How do I get a valid certification path?

EDIT: I'm not using this URL to directly create a connection, I am passing the URL to an itext PDFReader, which is then having the connection issue.

Sandip Armal Patil
  • 6,241
  • 21
  • 93
  • 160
RodeoClown
  • 13,338
  • 13
  • 52
  • 56

5 Answers5

3

You probably need to setup a HostnameVerifier. Before connecting, you need add it to the connection object

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(new HostnameVerifier() {
  public boolean verify(String hostname, SSLSession session) {
    // check hostname/session
    return true;
  }
});
conn.connect();
// read/write...

There certainly are some implementations out there, if you need one. You might want to look at HttpClient project too.

sblundy
  • 60,628
  • 22
  • 121
  • 123
3

Another thing to look at is the TrustManager you are using. The error message suggests that the certificate presented by the server is not signed by a trusted root. Since you don't have direct control over the SSL socket that is created, I think your best bet is to initialize your own SSLContext with a TrustManager that's been setup with the root CA of the server's certificate chain. Then set this context as the default.

This is assuming you are using Java 6. The API is more limited in Java 5. You can get a default SSLSocketFactory, but there's no standard way to set it.

erickson
  • 265,237
  • 58
  • 395
  • 493
0

The problem it's complaining about is that when you create an SSL connection, the server must present a valid certificate to the client. You can write an appropriate endpoint in Java (HTTPServerSocket will do it I think) but it would require some hacking about to set it up. It's probably easier to set up a local web server with anything that handles SSL correctly --- Apache, lighttp, whatever --- and create a self-signed cert using the openssl tools.

Updated

Here's an example from the Java Almanac. http://www.exampledepot.com/egs/javax.net.ssl/Server.html

An SSL server socket requires certificates that it will send to clients for authentication. The certificates must be contained in a keystore whose location must be explicitly specified (there is no default). Following the example we describe how to create and specify a keystore for the SSL server socket to use.

try {
    int port = 443;
    ServerSocketFactory ssocketFactory = SSLServerSocketFactory.getDefault();
    ServerSocket ssocket = ssocketFactory.createServerSocket(port);

    // Listen for connections
    Socket socket = ssocket.accept();

    // Create streams to securely send and receive data to the client
    InputStream in = socket.getInputStream();
    OutputStream out = socket.getOutputStream();

    // Read from in and write to out...

    // Close the socket
    in.close();
    out.close();
} catch(IOException e) {
}

Specify the keystore of certificates using the javax.net.ssl.keyStore system property:

> java -Djavax.net.ssl.keyStore=mySrvKeystore -Djavax.net.ssl.keyStorePassword=123456 MyServer
Charlie Martin
  • 110,348
  • 25
  • 193
  • 263
  • I have a working HTTPS server running, I just can't connect to it with the java URL class (updating main post to reflect this) – RodeoClown Dec 17 '08 at 02:58
0

It may also help you to add the certificate that the localhost server is using (I assume it's self-signed) to the JVM's keystore, using the "keytool" utility. This should have the effect of telling the JVM "you can trust this certificate".

Lalit Umbarkar
  • 443
  • 7
  • 15
matt b
  • 138,234
  • 66
  • 282
  • 345
0

I have ended up running a static method (only on dev) that installs a very trusting TrustManager (accepts everything), and also added a hostnameVerifier that always returns true (thanks sblundy).

Community
  • 1
  • 1
RodeoClown
  • 13,338
  • 13
  • 52
  • 56