If the Tomcat server (on Linux) is running with client-authentication=on (org.jboss.web.connector.ssl.client-auth=true), then the client (OSX 1.7.3) can download the JNLP (in browser), but the java-webstart can't download anything not even the JNLP again, only showing an empty certificate choosing dialog.
The certificates are self-signed ones. The CA and the Client certificates are imported into the OSX's KeyChain (ca->system, client+key->login)
Debugging the problem it seems so that the Apple's JNLP Java interface trying to reach the OSX's KeyChain keystore in a wrong way, without password (*see example below)
I made a small program based on debugging the running code on JNLP downloading (on OSX).
import java.security.Key;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.X509KeyManager;
public class OSXKeyChainTest {
/**
* Demonstrating issue in OSX-JNLP-Java interface, the keys from the
* KeyChain are not accessed during JNLP downloading phase. But if it would
* use any password it would work (see the FIXME line). This small test
* program is based on the debugging works on OSX 1.7.3.
*/
public static void main(String[] args) throws Exception {
KeyStore ks = KeyStore.getInstance("KeyChainStore", "Apple");
ks.load(null, new char[0]);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509", "SunJSSE");
// FIXME !!!! try it with ANY password, and it will work, eg. = new char[] {'x'};
char[] password = new char[] {};
// as AppleX509DeployKeyManager.getBrowserKeyManager() does
keyManagerFactory.init(ks, password);
X509KeyManager localX509KeyManager = null;
KeyManager[] arrayOfKeyManager = keyManagerFactory.getKeyManagers();
int i = 0;
while (i < arrayOfKeyManager.length) {
if ((arrayOfKeyManager[i] instanceof X509KeyManager)) {
localX509KeyManager = (X509KeyManager) arrayOfKeyManager[i];
break;
}
i++;
}
for (Enumeration<String> t = ks.aliases(); t.hasMoreElements();) {
String alias = t.nextElement();
System.out.println("@Alias: " + alias);
if (ks.isKeyEntry(alias)) {
System.out.println("It's a key entry");
for (Certificate c : ks.getCertificateChain(alias)) {
X509Certificate x509 = (X509Certificate) c;
System.out.println(x509.getSubjectDN().toString());
System.out.println("SN: " + x509.getSerialNumber());
}
// as SunX509KeyManagerImpl does
Key localKey = ks.getKey(alias, password);
System.out.println("Localkey: " + localKey);
}
}
System.out.println("--------------------------------");
System.out.println("It should be not null!: " + localX509KeyManager.getPrivateKey("client"));
}
}