1

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:

CONNECTED(00000003)
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);

        try
        {
            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)
            {
                result.append(line);
            }
            log.info("result=\n"+result);
        }
        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");
        //log.info("available="+getClass().getResourceAsStream(certFile).available());
        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 
subject=/O=Something/OU=Something/CN=Something.Something.com
issuer=/DC=net/DC=Something/DC=Something/CN=Something
-----BEGIN CERTIFICATE-----
(cert data)
-----END CERTIFICATE-----
Bag Attributes: <Empty Attributes>
subject=/O=Something/CN=Something
issuer=/O=Something/CN=Something
-----BEGIN CERTIFICATE-----
(cert data)
-----END CERTIFICATE-----
Bag Attributes: <Empty Attributes>
subject=/DC=Something/DC=Something/DC=Something/CN=Something
issuer=/O=Something/CN=Something
-----BEGIN CERTIFICATE-----
(cert data)
-----END CERTIFICATE-----

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 – Neil Smithline Nov 12 '15 at 1:10
  • What Neil said. Also: WireShark helps. Could you add the OpenSSL command line? And: what is the error message server side? – StackzOfZtuff Nov 12 '15 at 5:24
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.