0

Below is code I am using to create a TrustStore holding my Certificate Authority's public cert. I am creating another KeyStore to hold a "client certificate" which is one I created from a cert signing request and signed by the CA that I mentioned. For some reason, When I call sslCertSocketFactory.createSocket(), I get an exception thrown:

SSL failure: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x7780ef60: Failure in SSL library, usually a protocol error
    error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure (external/openssl/ssl/s3_pkt.c:1256 0x77829d10:0x00000003)

And on the server side, I get the following :

SSL alert (write): fatal: handshake failure
2014.07.01 15:56:46 LOG3[7121:4413599744]: SSL_accept: 140890C7: error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer did not return a certificate

What am I doing wrong? How do I make sure that the socket factory pushes the cert to the server that I specify in the localKeystore?

            // Load my CA's public cert from an InputStream

            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream caInput = new BufferedInputStream(cafile);
            Certificate ca = null;
            try {
                ca = cf.generateCertificate(caInput);

            } catch(Exception e) {
                Log.d(" Problem creating the CA cert: " + e.toString());
            }
            finally {
                caInput.close();
            }
            //sets this CA cert set as a KeyStore.TrustedCertificateEntry in the keystore.
            certManagerCA.trustCertificate((X509Certificate) ca);
            KeyStore keyStoreCA = certManagerCA.sslKeystore;

            tmf = TrustManagerFactory.getInstance("X509");
            tmf.init(keyStoreCA);

            localKeystore  = KeyStore.getInstance("BKS");
            try {
                //clientBKS is a bouncy castle keystore made with portecle from a public/private keypair signed by the CA I impored above
                localKeystore.load(clientBKS, "password".toCharArray());
            }
            finally {
                clientBKS.close();
            }

            // Build a KeyManager for Client auth
            kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(localKeystore, keyPass.toCharArray());
           //at this point I can iterate over the localKeyStore aliases and it ONLY has my cert in it. 

            sslCertSocketFactory = (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(100000);
            sslCertSocketFactory.setKeyManagers(kmf.getKeyManagers());
            sslCertSocketFactory.setTrustManagers(tmf.getTrustManagers());
            Socket test = sslCertSocketFactory.createSocket("10.22.1.100", 443);
Derek
  • 11,715
  • 32
  • 127
  • 228
  • Why are you doing all this? You only need *one* keystore, containing your private key, the signed certificate, and the CA certificate chain. – user207421 Jul 02 '14 at 01:23
  • Create your own key manager log everything in it, and check whether it returns your certificate or not. http://stackoverflow.com/questions/24476591/client-certificate-not-working-from-android-how-to-debug/24477846#24477846 – Than Jul 02 '14 at 12:44
  • @EJP It is true, that both keyStore and trustStore can be one file but its better to separate private and public credential both for security and maintenance reason. – Than Jul 02 '14 at 12:48
  • Thanks for the comments. I was actually just in the process of creating my own key manager for debugging this. I may try to combine the keystore and truststore to see what happens then. – Derek Jul 02 '14 at 17:50
  • @Than I have done as you mentioned in the other question you referenced. I am using SSLCertificateSocketFactory specifically. Anyhow, I put breakpoints in tall the methods of my own key manager, and I don't ever break at them. I set the key manager using: `SSLCertificateSocketFactory sslCertSocketFactory.setKeyManagers(new KeyManager[]{km});` – Derek Jul 02 '14 at 21:18
  • Check if keymanager's methods returns null. Your server said: "peer did not return a certificate", so probably you have wrong cert/private key in keystore, or keymanager isn't able to choose alias correctly. – Than Jul 03 '14 at 00:34
  • @Than I didn't say anything about using the same file for both the keystore and the truststore. I am violently against it. What I did say was to use the same file for the private key and the signed certificate and *its own certificate chain*, contrary to what the OP is doing here. This has nothing to do with truststores whatsoever. – user207421 Jul 03 '14 at 01:32
  • I ended up making a X509TrustManager wrapper as well. In the checkServerTrusted() I see a cert chain that includes my server's certificate. There is one other entry that looks like it could be my CA. (The servers cert was signed by the CA). I don't know what to make of that - how can I tell whether or not the server's cert was trusted? Someone suggested maybe I'm not seeing the KeyManager called because the server cert wasn't being trusted. – Derek Jul 03 '14 at 15:10

0 Answers0