1

I am trying to implement DynamoDBMapper from AWS but the application crashes when I try to connect to the AWS servers.

To start, I am running Android 4.4.2 on an Android Studio emulator and everything seems to be working fine. No problems there. Nonetheless, when I try to run on an actual device (running 4.4.2 on a Tablet... don't know the manufacturer), I get the following error:

Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6bffcdf0: 
     Failure in SSL library, usually a protocol error error:140740B5:SSL 
     routines:SSL23_CLIENT_HELLO:no ciphers available (external/openssl/ssl/s23_clnt.c:486 0x68474ce0:0x00000000)

Here is the full stack trace:

Caused by: com.amazonaws.AmazonClientException: Unable to execute HTTP request: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6bffcdf0: Failure in SSL library, usually a protocol error error:140740B5:SSL routines:SSL23_CLIENT_HELLO:no ciphers available (external/openssl/ssl/s23_clnt.c:486 0x68474ce0:0x00000000)

    com.amazonaws.http.AmazonHttpClient.executeHelper              AmazonHttpClient.java:421
    com.amazonaws.http.AmazonHttpClient.execute                    AmazonHttpClient.java:196
    com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke  AmazonDynamoDBClient.java:3257
    com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.getItem AmazonDynamoDBClient.java:904
    com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMapper.load  DynamoDBMapper.java:393
    com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMapper.load  DynamoDBMapper.java:466
    com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMapper.load  DynamoDBMapper.java:340
    @@@@.@@@@@.@@@@$@@@@.doInBackground  MainActivity.java:1259
    @@@@.@@@@@.@@@@$@@@@.doInBackground  MainActivity.java:1237
    android.os.AsyncTask$2.call          AsyncTask.java:288
    java.util.concurrent.FutureTask.run  FutureTask.java:237
    ... 4 more

Followed by:

Caused by: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6bffcdf0: Failure in SSL library, usually a protocol error error:140740B5:SSL routines:SSL23_CLIENT_HELLO:no ciphers available (external/openssl/ssl/s23_clnt.c:486 0x68474ce0:0x00000000)

    com.android.org.conscrypt.NativeCrypto.SSL_do_handshake          Native Method
    com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake       OpenSSLSocketImpl.java:406
    com.android.okhttp.Connection.upgradeToTls                       Connection.java:146
    com.android.okhttp.Connection.connect                            Connection.java:107
    com.android.okhttp.internal.http.HttpEngine.connect              HttpEngine.java:294
    com.android.okhttp.internal.http.HttpEngine.sendSocketRequest    HttpEngine.java:255
    com.android.okhttp.internal.http.HttpEngine.sendRequest          HttpEngine.java:206
    com.android.okhttp.internal.http.HttpURLConnectionImpl.execute   HttpURLConnectionImpl.java:345
    com.android.okhttp.internal.http.HttpURLConnectionImpl.connect   HttpURLConnectionImpl.java:89
    com.android.okhttp.internal.http.HttpURLConnectionImpl.getOutputStream   HttpURLConnectionImpl.java:197
    com.android.okhttp.internal.http.HttpsURLConnectionImpl.getOutputStream  HttpsURLConnectionImpl.java:254
    com.amazonaws.http.UrlHttpClient.writeContentToConnection        UrlHttpClient.java:128
    com.amazonaws.http.UrlHttpClient.execute                         UrlHttpClient.java:65
    com.amazonaws.http.AmazonHttpClient.executeHelper                AmazonHttpClient.java:353
    ... 14 more

And here is my sourcecode:

BasicAWSCredentials awsCredentials = new BasicAWSCredentials("abcdef12345","blahblahblah");
AmazonDynamoDBClient dynamoDBClient = new AmazonDynamoDBClient(awsCredentials);
DynamoDbMapper dbMapper = new DynamoDBMapper(dynamoDBClient);

//.... then eventually .....

AWSDriverNameTable awsDriverNameTable = dbMapper.load(AWSDriverNameTable.class, merchantID);

It is that last line of code where the error begins.

Now, I have looked around on SO and a few search engines and have learned that some Android devices fall back to SSL v3, while the server I am trying to connect to uses TLS v1.0 (went to www.ssllabs.com and found out that it does use TLS 1.0). Here is another SO question where someone seems to have solved an issue very similiar to this:

How to disable SSLv3 in android for HttpsUrlConnection?

Thus, if this is what is causing the issue (SSLv3 needing to be removed), how can I go about configuring the AmazonDynamoDbClient to use only TLS 1.0? I noticed you can create a ClientConfiguration and use:

clientConfiguration.getApacheHttpClientConfig().setSslSocketFactory(NoSSLv3SocketFactory);

and supply it with the awsCredentials in the AmazonDynamoDbClient constructor. But, it accepts:

org.apache.http.conn.ssl.SSLSocketFactory

not

javax.net.ssl.SSLSocketFactory

which is what is used in the answer from the link I provided (not to mention Android Studio is informing me that org.apache.http.conn.ssl.SSLSocketFactory is deprecated).

At any rate, any help with this matter would be much appreciated. Thanks!

Community
  • 1
  • 1
SydStorm
  • 68
  • 7
  • What AWS SDK are you using? – Yangfan Jan 12 '16 at 19:59
  • I have added these to my gradle file: compile 'com.amazonaws:aws-android-sdk-core:2.+' compile 'com.amazonaws:aws-android-sdk-cognito:2.+' compile 'com.amazonaws:aws-android-sdk-s3:2.+' compile 'com.amazonaws:aws-android-sdk-ddb:2.+' compile 'com.amazonaws:aws-android-sdk-ddb-mapper:2.+' so it should be the most recent. Also, I added: compile files('libs/aws-java-sdk-1.10.45.jar') to my project so I could use a ClientConfiguration that had the method "getApacheHttpClientConfig()". – SydStorm Jan 12 '16 at 21:51
  • You are not support to use aws-java-sdk which isn't meant for Android. FYI AWS SDK for Android uses HttpURLConnection as the default HTTP library. SSLv3 has been deprecated on all AWS services. It looks like your device can't negotiate with TLSv1.0+ protocol for some reason. In theory TLSv1.0 should be supported. I suggest you try it on a different device. – Yangfan Jan 12 '16 at 22:22
  • As it turns out, I have been informed that the device I am using, which is standard in the industry, uses TLSv1.2. After testing the server on ssllabs.com, I found that this protocol isn't supported by AWS... is this true? And if so does that mean there isn't a workout around either? – SydStorm Jan 13 '16 at 19:05

2 Answers2

0

You can use org.apache.http.conn.ssl.SSLConnectionSocketFactory instead of org.apache.http.conn.ssl.SSLSocketFactory.

From the JavaDoc of SSLSocketFactory (https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/conn/ssl/SSLSocketFactory.html) -

Deprecated. (4.3) use SSLConnectionSocketFactory

Rohan
  • 1,180
  • 2
  • 15
  • 28
0

Some services like Cognito support TLSv1.0+, while some say DynamoDB supports only TLSv1.0 (not above). If your device supports TLSv1.0, it should work then. Since you said the code works on emulator but not on the tablet, it's hard to say where the problem is. I suggest you try these:

Some notes from comments:

  • SSLv3 has been deprecated on all AWS services.
  • Remove aws-java-sdk and use aws-android-sdk. The latter has lots of optimizations for Android.
  • aws-android-sdk uses HttpURLConnection as the default HTTP library.

To test what protocols a service supports, use this command:

openssl s_client -connect dynamodb.us-west-2.amazonaws.com:443
Yangfan
  • 1,866
  • 1
  • 11
  • 13
  • Alright, thanks for the info. I will try out what you said and make the appropriate adjustments. – SydStorm Jan 13 '16 at 21:33
  • I have come to learn, as mentioned earlier, that the device where the crash occurred *only* supports TLS v1.2. Also, after running a server test at: [SSLLabs](https://www.ssllabs.com/ssltest/analyze.html?d=dynamodb.us-east-1.amazonaws.com&latest) it shows me that TLS v1.2 is not supported by the server I want to connect with. I take this to ultimately mean that the device is not be able to communicate with the Dynamo Servers until (if) Amazon updates their protocol to TLS v1.2? – SydStorm Jan 15 '16 at 00:25
  • The official [doc](http://developer.android.com/reference/javax/net/ssl/SSLSocket.html) says TLSv1.0 is enabled and supported by default. Not sure why your device doesn't support it. Given that, your device can't connect to DynamoDB directly until the service supports TLSv1.2. An alternative is to use [API Gateway](https://aws.amazon.com/api-gateway/) as a proxy to DynamoDB. API Gateway supports TLSv1.2. – Yangfan Jan 15 '16 at 00:53