trustAnchors parameter must be non-empty (in applet)
Hi all,
I am writing a sample app using RMI over SSL.
It works fine when I run it from the jar, from the command line, but when I try to run it from an applet, I get this error:
Exception occured:error during JRMP connection establishment; nested exception is:
javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at HelloImpl_Stub.sayHello(Unknown Source)
at HelloClient.<init>(HelloClient.java:116)
at applet.start(applet.java:57)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(Unknown Source)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(Unknown Source)
at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
at java.io.BufferedOutputStream.flush(Unknown Source)
at java.io.DataOutputStream.flush(Unknown Source)
... 8 more
Caused by: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at sun.security.validator.PKIXValidator.<init>(Unknown Source)
at sun.security.validator.Validator.getInstance(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.getValidator(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(Unknown Source)
... 12 more
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at java.security.cert.PKIXParameters.setTrustAnchors(Unknown Source)
at java.security.cert.PKIXParameters.<init>(Unknown Source)
at java.security.cert.PKIXBuilderParameters.<init>(Unknown Source)
... 24 more
This is my applet code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
publicclass appletextends JApplet
{
publicvoid start()
{
HelloClient app =new HelloClient();
app.setVisible(true);
}
}
And this is the code I use in HelloClient to use the keystore and truststore that are located inside the jar.
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore truststore = KeyStore.getInstance(KeyStore.getDefaultType());
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream keystoreStream = ClassLoader.getSystemResourceAsStream("keystore");
InputStream truststoreStream = ClassLoader.getSystemResourceAsStream("truststore");
truststore.load(truststoreStream,"trustword".toCharArray());
keystore.load(keystoreStream,"password".toCharArray());
trustManagerFactory.init(truststore);
keyManagerFactory.init(keystore,"password".toCharArray());
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(keyManagers, trustManagers,null);
SSLContext.setDefault(sc);
From this topic (the only one with any information on this problem)
http://forum.java.sun.com/thread.jspa?forumID=2&threadID=580496
It seems there are two possible errors...
One is that it can't find the truststore... but it finds it when I run the application (same class) from the cmd, so I am unsure whether this is the root cause of the error.
I tried using this line instead
ClassLoader.getSystemResourceAsStream("C:\\truststore");
and putting a copy of the truststore in C:\ but this didn't work either.
The other is that it isn't finding the root certificate for the truststore in the jvm cacerts. I exported the duke.cer from the truststore and imported that into the cacerts but still nothing changed.
Are my assumptions correct here, and is there anything I have missed?
I am using jre1.6.0_01 and for testing purposes, am using the keystore and truststore downloaded in the resources zip from
http://blogs.sun.com/lmalventosa/entry/using_the_ssl_tls_based
The jar is signed by anon self-signed certificate and using the getResourceAsStream, is able to load images throughout.
Thanks,
Brendo

