1

I am trying to post some data to a https URL, so I used the code I found in http://developer.android.com/reference/javax/net/ssl/HttpsURLConnection.html:

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

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

                // Open a HTTP  connection to  the URL
                conn = (HttpsURLConnection) url.openConnection();
                conn.setSSLSocketFactory(context.getSocketFactory());

The problem is, that I am getting this exception:

    Exception : java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
    javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

EXTRA INFO1: I can post successfully to the https: address without doing anything extra from my laptop's Terminal, this is the printout of the connection's verbose:

== Info: Connected to cloud.someserver.com (127.0.0.1) port 443 (#0)
== Info: TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
== Info: Server certificate: cloud.someserver.com
== Info: Server certificate: StartCom Class 1 Primary Intermediate Server CA
== Info: Server certificate: StartCom Certification Authority

EXTRA INFO2: This is the printout I get from console when I execute "openssl s_client -connect cloud.myserver.com:80" :

CONNECTED(00000003) 77152:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59/src/ssl/s23_clnt.c:618: Joshs-MacBook-Pro:~ JoshDBS$ openssl s_client -connect cloud.myserver.com:8080 connect: Connection refused connect:errno=61 Joshs-MacBook-Pro:~ JoshDBS$ openssl s_client -connect cloud.myserver.com:81 connect: Connection refused connect:errno=61 Joshs-MacBook-Pro:~ JoshDBS$ openssl s_client -connect cloud.myserver.com:80

CONNECTED(00000003)
77155:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59/src/ssl/s23_clnt.c:618:
Joshs-MacBook-Pro:~ JoshDBS$ openssl s_client -connect cloud.myserver.com:443
CONNECTED(00000003)
depth=0 /C=ES/CN=cloud.myserver.com/[email protected]
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 /C=ES/CN=cloud.myserver.com/[email protected]
verify error:num=27:certificate not trusted
verify return:1
depth=0 /C=ES/CN=cloud.myserver.com/[email protected]
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:/C=ES/CN=cloud.myserver.com/[email protected]
   i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 1 Primary Intermediate Server CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGQTCCBSmgAwIBAgIHBcg1dAivUzANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UE
(Lots of alphanumeric characters here)
-----END CERTIFICATE-----
subject=/C=ES/CN=cloud.myserver.com/[email protected]
issuer=/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 1 Primary Intermediate Server CA
---
No client certificate CA names sent
---
SSL handshake has read 2304 bytes and written 328 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: B67EED30382BE22A81F86884646480E967662A1559CA791B1B4DA8F06EDC
    Session-ID-ctx: 
    Master-Key: DE439EC4BEA0AA6E9B15836AD33DB46105D1A27544E0570E8EFF50D3BEF8F0725FC1A34343495D5ADAE192DD09838
    Key-Arg   : None
    Start Time: 1450886131
    Timeout   : 300 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---
closed

What value do I need to assign to the keystore instead of those three dots (...) and where do I get it from?

How can I POST data using HttpsURLConnection? (I can already post to simple http: URLs)

2 Answers 2

2

Try the following:

String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);

Also, what URL are you trying to access? It might not be in the Android's DataStore of trusted certificates, which means you'll have to do a bit more work to add a certificate to the DataStore yourself.

Let me know if you are still stuck and we'll further debug your issue.

Sign up to request clarification or add additional context in comments.

3 Comments

I tried your suggestion and got the same result, I also added some Extra info to the question that you may find useful. I am trying to connect to a development https url address, that is surely not in Android's data store.
Try the following: openssl s_client -connect host:port. Do you get a certificate back from the server?
Hi, @C2H6O I have retaken the issue after the holidays, I have added the info about the certificate I get back to the question. I didnt configure anything on my laptop, the Terminal just accepts the certificate with the command you told me. I guess I need to do something else in Android.
1

Try to disable the SSL Certification validation as explained here. This is recommended only for development purposes, not in a production environment. in a production environment you must install the convenient certificates.

 TrustManager[] trustAllCerts = new TrustManager[] {
        new X509TrustManager() {
          public java.security.cert.X509Certificate[] getAcceptedIssuers() {
           return null;
          }
          @Override
          public void checkClientTrusted(X509Certificate[] arg0, String arg1)
           throws CertificateException {}

          @Override
          public void checkServerTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {}

          }
     };

  SSLContext sc=null;
  try {
   sc = SSLContext.getInstance("SSL");
  } catch (NoSuchAlgorithmException e) {
   e.printStackTrace();
  }
  try {
   sc.init(null, trustAllCerts, new java.security.SecureRandom());
  } catch (KeyManagementException e) {
   e.printStackTrace();
  }
  HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

  // Create all-trusting host name verifier
  HostnameVerifier validHosts = new HostnameVerifier() {
  @Override
  public boolean verify(String arg0, SSLSession arg1) {
   return true;
  }
  };
  // All hosts will be valid
  HttpsURLConnection.setDefaultHostnameVerifier(validHosts);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.