| Sam Pinkerton 2004-07-07, 8:59 am |
| Hello all,
I am getting a ValidatorException ("No trusted certificate found")
when I attempt to make a connection to an SSL server that has a
certificate which is signed by an intermediate certificate rather
than a root certificate, even though the intermediate certificate
is itself signed by a root certificate. The examples I've tried
work when the server certificate is signed directly by a root
certificate but fail when an intermediate certificate is involved.
Browsers don't have a problem with either case (I've tried
Mozilla, Firebird, MSIE, and Opera).
I was able to make a test case work by downloading the needed
intermediate certificate from Verisign and using keytool to
install it in cacerts. But that's obviously a lame solution.
Is the Sun SSL implementation supposed to be able to follow a
certificate chain? Is this a bug, or am I doing something
wrong?
Please take a look at my test case below. Many thanks for your
help!
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.URL;
import java.net.URLConnection;
class HttpsTest
{
static PrintStream out = System.out;
String urlString;
public static void main(String[] args)
{
if (args.length != 1) {
out.println("Bad argument list (need just url)!");
System.exit(1);
}
try {
new HttpsTest(args[0]).run();
}
catch(Exception e) {
e.printStackTrace();
}
}
HttpsTest(String url) throws Exception
{
if (!url.startsWith("https:"))
throw new Exception("Must be a secure url (https:)!");
this.urlString = url;
}
void run() throws Exception
{
out.println("Connecting to '" + urlString + "' ...");
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
out.println("conn is a " + conn.getClass().getName());
InputStream is = (InputStream)conn.getContent();
byte[] buffer = new byte[16384];
FileOutputStream fos = new FileOutputStream("fubar.html");
int bytesReceived = 0;
while (true) {
int len = is.read(buffer);
if (len < 0)
break;
bytesReceived += len;
fos.write(buffer, 0, len);
}
fos.close();
out.println("Received " + bytesReceived + " bytes.");
Runtime.getRuntime().exec("cmd /c fubar.html");
}
}
Try running it with https://online.firstusa.com/. When I do, I
get the following output (under JDK 1.4.2):
Connecting to 'https://online.firstusa.com/' ...
conn is a sun.net.www.protocol.https.HttpsURLConnectionImpl
javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: No trusted certificate
found
at com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.a(DashoA6275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA6275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA6275)
at com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA6275)
at com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA6275)
at com.sun.net.ssl.internal.ssl.SunJSSE_ax.a(DashoA6275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA6275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.j(DashoA6275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(DashoA6275)
at sun.net.www.protocol.https.HttpsClient.afterConnect(DashoA6275)
at sun.net.www.protocol.https.AbstractDelegate...nection.connect(DashoA6275)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:615)
at java.net.URLConnection.getContent(URLConnection.java:585)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getContent(DashoA6275)
at HttpsTest.run(HttpsTest.java:41)
at HttpsTest.main(HttpsTest.java:21)
Caused by: sun.security.validator.ValidatorException: No trusted
certificate found
at sun.security.validator.SimpleValidator.buildTrustedChain(SimpleValidator.java:304)
at sun.security.validator.SimpleValidator.engineValidate(SimpleValidator.java:107)
at sun.security.validator.Validator.validate(Validator.java:202)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(DashoA6275)
at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(DashoA6275)
... 13 more
|