0

I am working on an android application which need to download through HTTPS connection. But I got SSLHandshakeException - handshake failed.

What I have done is as below

First,using openssl to get server certificate chain

openssl s_client -connect www.coles.com.au:443

And got

Certificate chain
 0 s:/C=AU/ST=Victoria/L=Hawthorn East/O=Coles Supermarkets Australia Pty Ltd/OU=Web Team/CN=coles.com.au
   i:/C=US/O=thawte, Inc./CN=thawte SSL CA - G2
 1 s:/C=US/O=thawte, Inc./CN=thawte SSL CA - G2
   i:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIE3zCCA8egAwIBAgIQfc9y5DSMNxERU663wd4m+DANBgkqhkiG9w0BAQsFADBB
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMuMRswGQYDVQQDExJ0
aGF3dGUgU1NMIENBIC0gRzIwHhcNMTUxMDMwMDAwMDAwWhcNMTgxMDI5MjM1OTU5
WjCBkTELMAkGA1UEBhMCQVUxETAPBgNVBAgMCFZpY3RvcmlhMRYwFAYDVQQHDA1I
YXd0aG9ybiBFYXN0MS0wKwYDVQQKDCRDb2xlcyBTdXBlcm1hcmtldHMgQXVzdHJh
bGlhIFB0eSBMdGQxETAPBgNVBAsMCFdlYiBUZWFtMRUwEwYDVQQDDAxjb2xlcy5j
b20uYXUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBoLhSH1Q/3YGQ
d0d5FEza3EaW4bWYDfHtg0oReJ8OvONWYpPgKZ0HZPUi6m6CDhWKXRmxZbiRDGQR
ihRYpAcRnw/DbkN6+eDSHU0I5eZD4YpdbhvAzeVOkiSyQXipvAJZFvomHsjCIvIu
g/2EInwAeTkgDSJY+PUbiiy+Ooko/H2XpjV0+C3eb2RY/pNV+Df5FG1bzVtEWNna
ncqYK9tJlyfDNM9TENzZdxmLtJsFYzlniJcxVgjPw4uSI4N3Cnr3n3PuSKSQuavl
D7k4H7wuwPvOn6l1wAj7fbgq16ZfF9vUvLXsn/yc99V1/7oYIVA4KDxgLhU10IVp
k2JPDZN9AgMBAAGjggGAMIIBfDApBgNVHREEIjAgghB3d3cuY29sZXMuY29tLmF1
ggxjb2xlcy5jb20uYXUwCQYDVR0TBAIwADBuBgNVHSAEZzBlMGMGBmeBDAECAjBZ
MCYGCCsGAQUFBwIBFhpodHRwczovL3d3dy50aGF3dGUuY29tL2NwczAvBggrBgEF
BQcCAjAjDCFodHRwczovL3d3dy50aGF3dGUuY29tL3JlcG9zaXRvcnkwDgYDVR0P
AQH/BAQDAgWgMB8GA1UdIwQYMBaAFMJPSFf80U+awF04fQ4F29kutVJgMCsGA1Ud
HwQkMCIwIKAeoByGGmh0dHA6Ly90ai5zeW1jYi5jb20vdGouY3JsMB0GA1UdJQQW
MBQGCCsGAQUFBwMBBggrBgEFBQcDAjBXBggrBgEFBQcBAQRLMEkwHwYIKwYBBQUH
MAGGE2h0dHA6Ly90ai5zeW1jZC5jb20wJgYIKwYBBQUHMAKGGmh0dHA6Ly90ai5z
eW1jYi5jb20vdGouY3J0MA0GCSqGSIb3DQEBCwUAA4IBAQAkm5BJW0u7ZJFGVWip
xo/poAFHNMImBfofz8WJGN/npJwLKV0mV8FX6dRPEAjPWWT+I/JonwX7VVxAgUWj
3bl+XdIU3hj8cRh3yDnEvhKVKs3orr/jQnxSNx4JZCwmPUIuKK58R1dYCRV/hT7l
YYDMXj+RrAjhrgu7IgZJDCV9kcznBqMdbHLOb/P4PX6j8CsCufS6iGjKhBHTL/49
uuL9ACqH6BgGVctm4kELGcyS6e+VJ9rHI3P+1muOk4wKEVjps9rbPOmpUTk8WhXb
RghAwHrtQZEZMIAVMg2ksCkl/NGRl64Q1W/lW2JHun6ApdXPsGzTvzp3+Kmhrf5p
mLNK
-----END CERTIFICATE-----
subject=/C=AU/ST=Victoria/L=Hawthorn East/O=Coles Supermarkets Australia Pty Ltd/OU=Web Team/CN=coles.com.au
issuer=/C=US/O=thawte, Inc./CN=thawte SSL CA - G2
---
No client certificate CA names sent
Peer signing digest: SHA1

Then go to thawte website(https://search.thawte.com/support/ssl-digital-certificates/index?page=content&id=SO26817&actp=RSS&viewlocale=en_US#links) to download CA certificate(tell me if I did wrong or from wrong place to download) which is thawte_SSL_CA_G2.cer

Third, I have below code to connect

String url = "https://www.coles.com.au";
        String strContent = "";
        HttpURLConnection connection;

        AssetManager assetManager = context.getAssets();
        InputStream caInput = null;

        try{
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            caInput = assetManager.open("thawte_SSL_CA_G2.cer");
            Certificate ca = cf.generateCertificate(caInput);

            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);

            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            SSLContext context = SSLContext.getInstance("TLS");
            context.init(null, tmf.getTrustManagers(), null);

            URL urlObj = new URL(url);

            HttpsURLConnection urlConnection =
                    (HttpsURLConnection)urlObj.openConnection();
            urlConnection.setSSLSocketFactory(context.getSocketFactory());
            InputStream in = urlConnection.getInputStream();

            BufferedReader reader = new BufferedReader(new InputStreamReader(in));

            while(null != (strContent= reader.readLine())){
                System.out.println(strContent);
            }
        }
        catch (IOException e){
             String exception = e.getMessage();
            System.out.println(exception);
        }

I use wireshark to capture and observe below happened

-> Client Hello
<- Server Hello
<- Certificate
<- Server Key Exchange
-> Client Key Exchange, Change Cipher Spec, Hello Request, Hello Request
<- FIN

Please help me on why I got handshake failed.

Bing Lan
  • 1,121
  • 1
  • 13
  • 26
  • Related, you should use the following `openssl s_client -connect www.coles.com.au:443 -tls1 -servername www.coles.com.au`. That gets you TLS 1.0 (not SSLv3), and uses Server Name Indication (SNI). – jww Jun 02 '16 at 22:10
  • @jww By using your command, the same result retrieved. Do I get the correct certificate? – Bing Lan Jun 03 '16 at 11:42
  • This worked for me: http://stackoverflow.com/a/27126109/1617737 – ban-geoengineering Oct 12 '16 at 16:45

1 Answers1

0

You should add all the ICA (intermediate certificates) and CA.

You could do the following

openssl s_client -showcerts -connect  www.coles.com.au:443 

Add all the certificates you receive to your trust store. (Strictly speaking only ICA and CA are enough in trust store)

Raghu K Nair
  • 3,854
  • 1
  • 28
  • 45
  • The server is misconfigured. It should send all necessary intermediates. Also see [Rule - Always Provide All Needed Certificates](http://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet#Rule_-_Always_Provide_All_Needed_Certificates) on the OWSP TLS Cheatsheet. The client will still need to trust the Root CA. It could trust the Intermediate CA, too. In this case, there's no need to trust the Root CA. In the end, the webmaster needs to fix their server. – jww Jun 02 '16 at 21:39
  • Yes you right server should present all certificate chain and in your java application you should be adding all ICAs along with CAs to trust store for validating the end entity certificate. – Raghu K Nair Jun 02 '16 at 22:54
  • @RaghuKNair I added all ICA and CA into keystore by specify both alias as "CA" and then I see SSLHandshakeException - trust anchor for certification path not found. I can see it mentioned in the doc jww addressed, however what I should do to fix it? – Bing Lan Jun 03 '16 at 12:17