I'm trying to use JCAPI to get the certificates out of the Microsoft Certificate Store and use them for client authentication to a Apache server.
Security.addProvider(new JCAPIProvider());
JCAPIProperties.setLogging(true);
JCAPIProperties.getInstance().setPrivateKeyExportable(true);
KeyStore jks = KeyStore.getInstance("msks", "JCAPI");
jks.load(null, null);
KeyStore ks2 = KeyStore.getInstance("msks", "JCAPI");
ks2.load(null, null);
JCAPIProperties.getInstance().setExclusiveMSCertStore(ks2,"Root");
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(jks, null);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks2);
SecureRandom sr = SecureRandom.getInstance("RNG", "JCAPI");
sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), sr);
URLConnection con = url.openConnection();
((HttpsURLConnection)con).setSSLSocketFactory(sc.getSocketFactory());
((HttpsURLConnection)con).setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, javax.net.ssl.SSLSession session) {
return true;
}
});
When I do this i get-
Exception in thread "main" com.pheox.jcapi.JCAPIJNIRuntimeException: Exception raised in JCAPI.DLL:
JCAPIKeyStore_getKey() - Could not acquire a key container handle.
Keyset does not exist
Error code: 0x80090016
at com.pheox.jcapi.CoreKeyStoreJNI.getKey(Native Method)
at com.pheox.jcapi.j.f(Unknown Source)
at com.pheox.jcapi.JCAPIKeyStore.engineGetKey(Unknown Source)
at java.security.KeyStore.getKey(KeyStore.java:763)
at com.sun.net.ssl.internal.ssl.SunX509KeyManagerImpl.<init>(SunX509KeyManagerImpl.java:113)
at com.sun.net.ssl.internal.ssl.KeyManagerFactoryImpl$SunX509.engineInit(KeyManagerFactoryImpl.java:4
at javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:239)
at syncadd.net.URLConnectionFactory.getCertificateURLConnection(URLConnectionFactory.java:122)
at syncadd.net.URLConnectionFactory.getCertificateURLConnection(URLConnectionFactory.java:89)
at syncadd.crypto.Card.run(Card.java:64)
at syncadd.crypto.Card.main(Card.java:101)
This exception happens on
kmf.init(jks, null);
If I get rid of the
JCAPIProperties.getInstance().setPrivateKeyExportable(true);
I get a little farther, but then I end up with-
... no IV used for this cipher
main, SEND TLSv1 ALERT: fatal, description = handshake_failure
main, WRITE: TLSv1 Alert, length = 2
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Error signing certificate verify
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:449)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:817)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1029)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1056)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1040)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:405)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:170)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:981)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
at syncadd.crypto.Card.run(Card.java:70)
at syncadd.crypto.Card.main(Card.java:101)
Caused by: java.security.InvalidKeyException: Modulus is missing
at sun.security.rsa.RSAKeyFactory.checkKey(RSAKeyFactory.java:112)
at sun.security.rsa.RSAKeyFactory.toRSAKey(RSAKeyFactory.java:76)
at com.sun.crypto.provider.RSACipher.engineGetKeySize(DashoA13*..)
at javax.crypto.Cipher.b(DashoA13*..)
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at java.security.Signature$CipherAdapter.engineInitSign(Signature.java:1202)
at java.security.Signature$Delegate.init(Signature.java:1076)
at java.security.Signature$Delegate.chooseProvider(Signature.java:1033)
at java.security.Signature$Delegate.engineInitSign(Signature.java:1106)
at java.security.Signature.initSign(Signature.java:49
at com.sun.net.ssl.internal.ssl.RSASignature.engineInitSign(RSASignature.java:10
at java.security.Signature$Delegate.engineInitSign(Signature.java:1104)
at java.security.Signature.initSign(Signature.java:49
at com.sun.net.ssl.internal.ssl.HandshakeMessage$CertificateVerify.<init>(HandshakeMessage.java:1213)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:715)
... 13 more
Any ideas?