I've been trying to troubleshoot issues with client authentication and am seeing different behaviour when connecting from a Java application vs OpenSSL.

A third party has provided me with a pfx, I've extracted the certificate and the key (which match each other) and attempted to initiate a connection using openssl. I get the following handshake failure:

SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=2 C = US, O = "VeriSign, Inc.", OU = VeriSign Trust Network, OU = "(c) 2006 VeriSign, Inc. - For authorized use only", CN = VeriSign Class 3 Public Primary Certification Authority - G5
verify return:1
depth=1 C = US, O = "VeriSign, Inc.", OU = VeriSign Trust Network, OU = Terms of use at https://www.verisign.com/rpa (c)10, CN = VeriSign Class 3 International Server CA - G3
verify return:1
depth=0 C = US, ST = Somewhere, L = Somewhere, O = The Third Party, OU = TTP, CN = thethirdparty.com
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server certificate request A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client certificate A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write certificate verify A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL3 alert read:fatal:handshake failure
SSL_connect:failed in SSLv3 read finished A
140735253803088:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:s3_pkt.c:1472:SSL alert number 40
140735253803088:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177:

The third party has also sent me a Java application, that uses the same pfx, and authenticates successfully. The code is as follows:

    private void postHTTPSUsingClientAuth()
        log.info("starting test");
        final String url="https://thethirdpartyendpoint.com";
        final String GUID = "(A guid)";
        final String KEY = "(A key)";
        final String DATA = "Any Data";
        final String clientCert="/testdata/theClientCert.pfx";
        final String password = "password here";

        log.info("using URL: "+url);
        log.info("using guid | key: "+GUID+" | "+KEY);
        log.info("using certificate: "+clientCert);

            KeyStore keyStore = getKeyStore(clientCert,password);
            CloseableHttpClient client=getHttpClientWithClientCert(keyStore,password);
            HttpPost request = new HttpPost(url);
            request.addHeader("clientId", GUID);
            request.addHeader("key", KEY);
            request.setEntity(new StringEntity(DATA));

            // add request header
            HttpResponse response = client.execute(request);
            log.info("got response: "+response.getStatusLine().getStatusCode());

            BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            StringBuffer result = new StringBuffer();
            String line = "";
            log.info("writing response");
            while ((line = rd.readLine()) != null)
        catch (Exception e)
            log.error("error occurred: "+e.toString());
        log.info("test complete");

private KeyStore getKeyStore(String certFile, String password) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        //log.info("testing resource location");
        keyStore.load(getClass().getResourceAsStream(certFile), password.toCharArray());
        return keyStore;

    private CloseableHttpClient getHttpClientWithClientCert(KeyStore keyStore, String password) throws Exception
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
        keyManagerFactory.init(keyStore, password.toCharArray());
        final SSLContext context = SSLContext.getInstance("TLS");
        context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
        return HttpClientBuilder.create()
                .setSSLSocketFactory(new SSLConnectionSocketFactory(context)).build();      

Can anyone explain why, when using the same certificate, the handshake fails for OpenSSL?

The client certificate contains a chain:

Bag Attributes
    localKeyID: 01 00 00 00 
(cert data)
Bag Attributes: <Empty Attributes>
(cert data)
Bag Attributes: <Empty Attributes>
(cert data)

Is there a chance that OpenSSL omits this chain, and only sends the top cert?

  • You can hook up a debugging proxy like Fiddler3 to see what is being transmitted Nov 12, 2015 at 1:10
  • What Neil said. Also: WireShark helps. Could you add the OpenSSL command line? And: what is the error message server side? Nov 12, 2015 at 5:24

1 Answer 1


My guess is that you have simply added leaf certificate and chain certificate to the same file and then used openssl s_client -cert file.pem on it. But, the documentation for s_client states:

-CAfile file
    A file containing trusted certificates to use during server authentication
    and to use when attempting to build the client certificate chain.

This means that you have to give the leaf certificate with the -cert option but add the chain certificates with the -CAfile option. See also https://stackoverflow.com/questions/7199095/how-s-client-present-client-certificate-chain

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .