10

My project has been using Android Volley network framework for a long time, but recently I found a SSL 3.0 protocol bug published on the Internet.

I want to know how can I find out what's the TLS version my project used, and how to confirm whether the library is updated.

Here is my source code fragment:

HttpStack stack = new HurlStack();
Network network = new BasicNetwork(stack);
mHttpRequestQueue = new RequestQueue(new NoCache(), network);
mHttpRequestQueue.start();

I think the point is in HurlStack class, and it depends on org.apache.http package, but I can't figure out where TLS/SSL configuration is.

Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38
Alex Wang
  • 131
  • 1
  • 1
  • 10

3 Answers3

20

You may modify the version of TLS used in Volley by creating a custom HTTPStack and setting the stack in the Volley.newRequestQueue(context, httpStack) method in Volley.java. Although, you only need to do this for Android versions 16-19. Before v16, TLS 1.2 isn't supported and after v19, TLS 1.2 is enabled by default. So, you should focus on manually setting TLS to 1.2 for Android versions 16-19.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
    && Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
    try {
      ProviderInstaller.installIfNeeded(getContext());
    } catch (GooglePlayServicesRepairableException e) {
      // Indicates that Google Play services is out of date, disabled, etc.
      // Prompt the user to install/update/enable Google Play services.
      GooglePlayServicesUtil.showErrorNotification(e.getConnectionStatusCode(), getContext());
      // Notify the SyncManager that a soft error occurred.
      syncResult.stats.numIOExceptions++;
      return;
    } catch (GooglePlayServicesNotAvailableException e) {
      // Indicates a non-recoverable error; the ProviderInstaller is not able
      // to install an up-to-date Provider.
      // Notify the SyncManager that a hard error occurred.
      syncResult.stats.numAuthExceptions++;
      return;
    }

    HttpStack stack = null;
    try {
      stack = new HurlStack(null, new TLSSocketFactory());
    } catch (KeyManagementException e) {
      e.printStackTrace();
      Log.d("Your Wrapper Class", "Could not create new stack for TLS v1.2");
      stack = new HurlStack();
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
      Log.d("Your Wrapper Class", "Could not create new stack for TLS v1.2");
      stack = new HurlStack();
    }
    requestQueue = Volley.newRequestQueue(context, stack);
} else {
  requestQueue = Volley.newRequestQueue(context);
}

And then use a TLSSocketFactory class which extends SSLSocketFactory like the one Florian Krauthan created here, where the v1.2 TLS protocol is enabled: https://gist.github.com/fkrauthan/ac8624466a4dee4fd02f#file-tlssocketfactory-java

w3bshark
  • 2,700
  • 1
  • 30
  • 40
  • 3
    I had to also upgrade the Security provider as per https://blog.dev-area.net/2015/08/17/protect-your-android-app-against-ssl-exploits/ before it worked on my 4.4 device – Diederik Mar 10 '17 at 08:44
  • 2
    @Diederik's point is VERY important. The code must handle the security code provider's update. In my case, even the security provider was updated already by another app, i still had to include the code in my own app to make TLS work. – Ajji Oct 10 '17 at 11:45
  • 4
    @Ajji I've updated answer to include checking to ensure the security provider has the latest updates. For others out there, you can read more from the official docs on this here: https://developer.android.com/training/articles/security-gms-provider.html This can either be done synchronously (like it is in my answer) or asynchronously. But, it MUST be done. – w3bshark Jan 29 '18 at 14:07
  • Android complains that HttpStack is deprecated. I implemented the asynchronous version of your link and it works without the HttpStack and TLSSocketFactory on the emulator with API 19. Is it ok to just skip that part? –  Apr 22 '20 at 10:48
1

On Android the used TLS version mostly depends on the used Android version. Apache Volley bases on Apache Http Client which bases on HttpsUrlConnection, therefore the standard SSL/TLS SSLSocketFactory is used.

On Android below 4.3 usually only SSLv3 and TLS 1.0 are supported. On later versions TLS 1.1 and 1.2 are often supported but disabled.

Starting with Android 5 TLS 1.1 and TLS 1.2 are supported and enabled by default

Robert
  • 39,162
  • 17
  • 99
  • 152
  • Then where can I find TLS version in my source code?Could you point it out the precise position? I need to confirm completely that. – Alex Wang Jul 08 '15 at 09:10
  • As long as you don't set-up an custom SSLSocketFactory your code does not specify the TLS version. That is all done in the Android API runtime code. – Robert Jul 08 '15 at 09:34
  • There should be a way to enable TLS v1.2 for Volley for Android versions 16-20 since it's supported but not enabled by default. Could you point us to Volley documentation where this may be possible? Unfortunately, saying "That is all done in the Android API runtime code", is not very helpful. The OkHttp library offers the ability to set the TLS version: http://stackoverflow.com/questions/29249630/android-enable-tlsv1-2-in-okhttp – w3bshark Nov 23 '15 at 14:07
0

@w3bshark's answer worked for me. But Before using that code, Make sure you include the code to update Security Provider. In my case, TLS didn't work until i update security provider. Following is the code to update it.

private void updateAndroidSecurityProvider() {
    try {
        ProviderInstaller.installIfNeeded(this);
    } catch (GooglePlayServicesRepairableException e) {
        Log.e("Test321", "PlayServices not installed");
    } catch (GooglePlayServicesNotAvailableException e) {
        Log.e("Test321", "Google Play Services not available.");
    }
}
Ajji
  • 3,068
  • 2
  • 30
  • 31