0

I'm trying to develop an app to communicate with amazon alexa using OKhttp3. Everything was working fine while I was trying the app on an android API 26. But once I started using an android API 19 every request to https://avs-alexa-na.amazon.com/ started failing.

Before working for API 19 this was how I used this function to open the down channel.

    final String url = "https://avs-alexa-na.amazon.com/";
    final String version = "v20160207";
    final Request request = new Request.Builder()
            .get()
            .header("Authorization", "Bearer " + myApplication.getAccessToken())
            .url(url + version + "/directives")
            .build();
    try {
        final OkHttpClient client = new OkHttpClient();
        Response response = client.newCall(request).execute();
        Log.i("Down channel", "opened");
    } catch (Exception ex) {
        Log.e("Down channel", "error Sending request " + ex.getLocalizedMessage());
    }


But now this same function returns javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb969de80: Failure in SSL library, usually a protocol error error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x8d954990:0x00000000)

So after following some posts on line I learned that android 19 doesn't install by default TLSv1.2 so I added a function to install it and started having this error :unexpected end of stream on Connection{avs-alexa-na.amazon.com:443, proxy=DIRECT@ hostAddress=avs-alexa-na.amazon.com/54.239.39.74:443 cipherSuite=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 protocol=http/1.1}

I started exploring other ways working with certificates (my certificate, and the one from amazon gotten by openssl s_client -connect avs-alexa-eu.amazon.com:443:

SSLContext sslContext;
    TrustManager[] trustManagers;
    try {
        final KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        final InputStream certInputStream = activity.getResources().openRawResource(R.raw.cert);
        InputStream avscertInputStream = activity.getResources().openRawResource(R.raw.amazon_avs_cert);
        final CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        final Certificate cert = certificateFactory.generateCertificate(certInputStream);
        final Certificate avscert = certificateFactory.generateCertificate(avscertInputStream);
        keyStore.setCertificateEntry("amazon_avs", avscert);
        keyStore.setCertificateEntry("cert", cert);
        final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(keyStore);
        trustManagers = trustManagerFactory.getTrustManagers();
        sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(null, trustManagers, null);
        return new OkHttpClient.Builder()
                .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustManagers[0])
                .build();
    } catch (Exception e) {
        e.printStackTrace();
        return new OkHttpClient();
    }

But it led to a java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

I'm lost, I don't know what I did wrong or what I did not do. Thanks for you help.

faz95
  • 48
  • 5
  • did you find the solution ? I am also getting same issue. First time I can able to play. then later throwing the exception – AngelJanniee Nov 29 '17 at 12:04
  • No I'm still stuck with this problem. – faz95 Nov 29 '17 at 15:36
  • Did you manage to fix the issue? – anoop4real May 21 '18 at 11:01
  • Yes and no, turns out the problem was with http2 not being implemented in those old version of android an libs like jetty or okhttp not implementing it either for older OS. So I just created a proxy to work around it and it works fine. – faz95 May 22 '18 at 03:11

0 Answers0