HTTPSURLConnection/JSSE
Hi...I am having some difficulty making a secure connection to send/receive streams. In order to connect to non-secure sites, I use the following code:
// Initialize URL variables
URL url = null;
HttpURLConnection urlConnection = null;
// Get handle to URL and its connection
url = new URL("http://www.whatever.com");
urlConnection = (HttpURLConnection)url.openConnection();
// Open input/output stream
[Add code to open stream(s) here]
// Clean up
[Add code to close stream(s) here]
This code works fine. When I change the URL to a "HTTPS" URL, the code throws a malformed URL exception. I understand that this is because the HTTPS protocol is not understood and JSSE must be used. So, I installed JSSE in the appropriate directory, added the JAR files to my class path, and changed the above code to this:
// Initialize URL variables
URL url = null;
HttpsURLConnection urlConnection = null;
// Add provider
System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
// Get handle to URL and its connection
url = new URL("https://www.whatever.com");
urlConnection = (HttpsURLConnection)url.openConnection();
// Open input/output stream
[Add code to open stream(s) here]
// Clean up
[Add code to close stream(s) here]
Unfortunately, the code blows up when I try to open an input or output stream. I get the following in the log:
java.net.SocketException: SSL implementation not available at javax.net.ssl.DefaultSSLSocketFactory.createSocket([DashoPro-V1.2-120198]) at com.sun.net.ssl.internal.www.protocol.https.HttpsClient.doConnect([DashoPro-V1.2-120198])at com.sun.net.ssl.internal.www.protocol.https.NetworkClient.openServer([DashoPro-V1.2-120198]) at com.sun.net.ssl.internal.www.protocol.https.HttpClient.l([DashoPro-V1.2-120198]) at com.sun.net.ssl.internal.www.protocol.https.HttpClient.<init>([DashoPro-V1.2-120198]) at com.sun.net.ssl.internal.www.protocol.https.HttpsClient.<init>([DashoPro-V1.2-120198]) at com.sun.net.ssl.internal.www.protocol.https.HttpsClient.a([DashoPro-V1.2-120198]) at com.sun.net.ssl.internal.www.protocol.https.HttpsClient.a([DashoPro-V1.2-120198]) at com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnection.connect([DashoPro-V1.2-120198]) at com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnection.getInputStream([DashoPro-V1.2-120198])
at https_test.executeTest(https_test.java:91)
at https_test.service(https_test.java:133)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853) at allaire.jrun.servlet.JRunSE.service(../servlet/JRunSE.java:1416) at allaire.jrun.session.JRunSessionService.service(../session/JRunSessionService.java:1082)
at allaire.jrun.servlet.JRunSE.runServlet(../servlet/JRunSE.java:1270) at allaire.jrun.servlet.JRunRequestDispatcher.forward(../servlet/JRunRequestDispatcher.java:89)
at allaire.jrun.servlet.JRunSE.service(../servlet/JRunSE.java:1552) at allaire.jrun.servlet.JRunSE.service(../servlet/JRunSE.java:1542)
at allaire.jrun.servlet.JvmContext.dispatch(../servlet/JvmContext.java:364)
at allaire.jrun.http.WebEndpoint.run(../http/WebEndpoint.java:115)
at allaire.jrun.ThreadPool.run(../ThreadPool.java:272)
at allaire.jrun.WorkerThread.run(../WorkerThread.java:75)
java.net.SocketException: SSL implementation not availableat javax.net.ssl.DefaultSSLSocketFactory.createSocket([DashoPro-V1.2-120198]) at com.sun.net.ssl.internal.www.protocol.https.HttpsClient.doConnect([DashoPro-V1.2-120198])at com.sun.net.ssl.internal.www.protocol.https.NetworkClient.openServer([DashoPro-V1.2-120198]) at com.sun.net.ssl.internal.www.protocol.https.HttpClient.l([DashoPro-V1.2-120198]) at com.sun.net.ssl.internal.www.protocol.https.HttpClient.<init>([DashoPro-V1.2-120198]) at com.sun.net.ssl.internal.www.protocol.https.HttpsClient.<init>([DashoPro-V1.2-120198]) at com.sun.net.ssl.internal.www.protocol.https.HttpsClient.a([DashoPro-V1.2-120198])at com.sun.net.ssl.internal.www.protocol.https.HttpsClient.a([DashoPro-V1.2-120198])at com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnection.connect([DashoPro-V1.2-120198]) at com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnection.getInputStream([DashoPro-V1.2-120198])
at https_test.executeTest(https_test.java:93)
at https_test.service(https_test.java:135)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at allaire.jrun.servlet.JRunSE.service(../servlet/JRunSE.java:1416) at allaire.jrun.session.JRunSessionService.service(../session/JRunSessionService.java:1082)
at allaire.jrun.servlet.JRunSE.runServlet(../servlet/JRunSE.java:1270) at allaire.jrun.servlet.JRunRequestDispatcher.forward(../servlet/JRunRequestDispatcher.java:89)
at allaire.jrun.servlet.JRunSE.service(../servlet/JRunSE.java:1552)
at allaire.jrun.servlet.JRunSE.service(../servlet/JRunSE.java:1542)
at allaire.jrun.servlet.JvmContext.dispatch(../servlet/JvmContext.java:364)
at allaire.jrun.http.WebEndpoint.run(../http/WebEndpoint.java:115)
at allaire.jrun.ThreadPool.run(../ThreadPool.java:272)
at allaire.jrun.WorkerThread.run(../WorkerThread.java:75)
I have tried both static and dynamic registration, and both at the same time! For static registration, I do the following:
1. Copied the 3 JSSE JAR files to $JREHOME/lib/ext
2. Modified the java.security file to add the additional security provider
For dymaic registration, I do the following:
1. Added the 3 JAR files to my classpath
2. Added a line (shown in code above) to dynamically add the provider
I feel like I have done everything but it still does not work! Any help would be greatly appreciated. Thanks!!
[5993 byte] By [
jingeno] at [2007-9-26 5:25:44]

I have received this error using the cacerts file from Visual Cafe which is corrupt.Use the one with the jdk 1.3.1 if you desire or the 1.4 betaGood luck
Hi,Please use HTTPClient package available from apacheby using this package u can have manay advantages over some java.net classess Istikhar
In what order did you put the security provider in when you modified the java.security file. I added it as the second provider in the list, only behind the original default provider and it eliminated that error
//original default provider
security.provider.1=sun.security.provider.Sun
//provider necessary for SSL com
security.provider.2=com.sun.net.ssl.internal.ssl.Provider
I actually had it as the third...I switched it to the second but I still get the error. :( Thanks for the reply though.
I've run into the same problem. Have you solved id?
afloom at 2007-6-29 19:33:38 >

Ok, solved it myself. Seems as if the issue is the order of doing things. Change the order of adding the provider and settings the system property, and it should work. Like this:
java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
However, I now get this exception:
javax.net.ssl.SSLException: untrusted server cert chain
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a([DashoPro-V1.2-120198])
at com.sun.net.ssl.internal.ssl.ClientHandshaker.a([DashoPro-V1.2-120198])
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage([DashoPro-V1.2-120198])
at com.sun.net.ssl.internal.ssl.Handshaker.process_record([DashoPro-V1.2-120198])
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a([DashoPro-V1.2-120198])
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a([DashoPro-V1.2-120198])
at com.sun.net.ssl.internal.ssl.AppOutputStream.write([DashoPro-V1.2-120198])
at java.io.OutputStream.write(OutputStream.java:61)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake([DashoPro-V1.2-120198])
at com.sun.net.ssl.internal.www.protocol.https.HttpsClient.doConnect([DashoPro-V1.2-120198])
at com.sun.net.ssl.internal.www.protocol.https.NetworkClient.openServer([DashoPro-V1.2-120198])
at com.sun.net.ssl.internal.www.protocol.https.HttpClient.l([DashoPro-V1.2-120198])
at com.sun.net.ssl.internal.www.protocol.https.HttpClient.([DashoPro-V1.2-120198])
at com.sun.net.ssl.internal.www.protocol.https.HttpsClient.([DashoPro-V1.2-120198])
at com.sun.net.ssl.internal.www.protocol.https.HttpsClient.a([DashoPro-V1.2-120198])
at com.sun.net.ssl.internal.www.protocol.https.HttpsClient.a([DashoPro-V1.2-120198])
at com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnection.connect([DashoPro-V1.2-120198])
afloom at 2007-6-29 19:33:38 >

I have tried (and tried again today) reversing the order of the addProvider and System.setProperty statements, but unfortunately that didn't change anything for me.
Set this property in your code, and implement something like the verifier class below.
com.sun.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(new SSLHostnameCheck());
...
...
...
public class SSLHostnameCheck implements com.sun.net.ssl.HostnameVerifier {
public SSLHostnameCheck() {
}
public boolean verify(String host, String cert) {
System.out.println("I accept any certificate and host name combo!");
return true;
}
}
[afloom],
> Ok, solved it myself. Seems as if the issue is the
> order of doing things. Change the order of adding the
> provider and settings the system property, and it
> should work. Like this:
>
> java.security.Security.addProvider(new
> com.sun.net.ssl.internal.ssl.Provider());
> System.setProperty("java.protocol.handler.pkgs",
> "com.sun.net.ssl.internal.www.protocol");
>
> However, I now get this exception:
>
> javax.net.ssl.SSLException: untrusted server cert
> chain
> at
> com.sun.net.ssl.internal.ssl.SSLSocketImpl.a([DashoPro
> V1.2-120198])
> at
> com.sun.net.ssl.internal.ssl.ClientHandshaker.a([Dasho
> ro-V1.2-120198])
> at
> com.sun.net.ssl.internal.ssl.ClientHandshaker.processM
> ssage([DashoPro-V1.2-120198])
> at
> com.sun.net.ssl.internal.ssl.Handshaker.process_record
> [DashoPro-V1.2-120198])
> at
> com.sun.net.ssl.internal.ssl.SSLSocketImpl.a([DashoPro
> V1.2-120198])
> at
> com.sun.net.ssl.internal.ssl.SSLSocketImpl.a([DashoPro
> V1.2-120198])
> at
> com.sun.net.ssl.internal.ssl.AppOutputStream.write([Da
> hoPro-V1.2-120198])
> at java.io.OutputStream.write(OutputStream.java:61)
> at
> com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandsh
> ke([DashoPro-V1.2-120198])
> at
> com.sun.net.ssl.internal.www.protocol.https.HttpsClien
> .doConnect([DashoPro-V1.2-120198])
> at
> com.sun.net.ssl.internal.www.protocol.https.NetworkCli
> nt.openServer([DashoPro-V1.2-120198])
> at
> com.sun.net.ssl.internal.www.protocol.https.HttpClient
> l([DashoPro-V1.2-120198])
> at
> com.sun.net.ssl.internal.www.protocol.https.HttpClient
> ([DashoPro-V1.2-120198])
> at
> com.sun.net.ssl.internal.www.protocol.https.HttpsClien
> .([DashoPro-V1.2-120198])
> at
> com.sun.net.ssl.internal.www.protocol.https.HttpsClien
> .a([DashoPro-V1.2-120198])
> at
> com.sun.net.ssl.internal.www.protocol.https.HttpsClien
> .a([DashoPro-V1.2-120198])
> at
> com.sun.net.ssl.internal.www.protocol.https.HttpsURLCo
> nection.connect([DashoPro-V1.2-120198])
The exception:
javax.net.ssl.SSLException: untrusted server cert chain
, is usually caused by an EXPIRED certificate within a public key certificate chain.
This was seen with JSSE 1.0 and with JSSE 1.0.1, the specification has relaxed this rule for certificate signing i.e. if a certificate in the chain has expired, JSSE 1.0.1 will consult a local file for updated certificate information.
Check the expiry date of the certificate in your keystore.
HTH.
Allen Lai
Developer Technical Support
SUN Microsystems
http://www.sun.com/developer/support/
Yes, I hadn't realized that I needed to import the certificate. Their is an absolutely beautiful description of this by Kieran Jones at: http://forums.java.sun.com/thread.jsp?forum=9&thread=14543Thanks Kieran!
afloom at 2007-6-29 19:33:38 >
