Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Volley fall back to SSLV3?

i am constantly monitoring my app errors and I see the following error too many times

 javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb8f0fc28: 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 0xaa48cd5c:0x00000000)-javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb8f0fc28: 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 0xaa48cd5c:0x00000000)

You can see the the error is about SSLV3 and my server support only TLSV1.2.

It seems like that on some clients Volley falls back to use SSLV3 (for some reason) and they get an error.

Users that get this error are on Android 4.4.2, 4.4.4 and 4.1.1 and more.

Interestingly enough I also use DefaultHttpClient in the same application, but it does not seem to report the same issue.

I am using the default HurlStack in Volley

I have seen the following... Disable SSL as a protocol in HttpsURLConnection

and https://code.google.com/p/android/issues/detail?id=78187

So what are my options?

  1. Is my assumption correct that Volley falls back to SSLV3?

  2. Why does volley fallback to SSLV3? In other words, what was the original failure that caused the fallback and how to resolve it?

  3. i I downloaded Volley recently, but I am not sure it is the latest. How do I find which version I have?.

Any thoughts?

like image 461
Oved Yavine Avatar asked Jul 17 '15 08:07

Oved Yavine


1 Answers

Your server does well not supporting SSLv3 since it has some security issues and should not be used.

When using Android versions prior to Kitkat you must use a socket factory that removes SSLv3 to be used as default configuration:

public class VolleyToolboxExtension extends Volley {
    /** Default on-disk cache directory. */
    private static final String DEFAULT_CACHE_DIR = "volley";

    /**
     * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it.
     *
     * @param context A {@link Context} to use for creating the cache dir.
     * @param stack An {@link HttpStack} to use for the network, or null for default.
     * @return A started {@link RequestQueue} instance.
     */
    public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
        File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
        String userAgent = "volley/0";
        try {
            String packageName = context.getPackageName();
            PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
            userAgent = packageName + "/" + info.versionCode;
        } catch (PackageManager.NameNotFoundException e) {

        }
        if (stack == null) {
            if (Build.VERSION.SDK_INT >= 9) {
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
                    // Use a socket factory that removes sslv3
                    stack = new HurlStack(null, new NoSSLv3Compat.NoSSLv3Factory());
                } else {
                    stack = new HurlStack();
                }
            } else {
                // Prior to Gingerbread, HttpUrlConnection was unreliable.
                // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
                stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
            }
        }
        Network network = new BasicNetwork(stack);
        RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
        queue.start();
        return queue;
    }

    /**
     * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it.
     *
     * @param context A {@link Context} to use for creating the cache dir.
     * @return A started {@link RequestQueue} instance.
     */
    public static RequestQueue newRequestQueue(Context context) {
        return newRequestQueue(context, null);
    }

}

NoSSLv3Compat class can be found here: https://github.com/Floens/volley/blob/master/src/com/android/volley/compat/NoSSLv3Compat.java

Use this extension to create your request queue:

    /**
     * @return The Volley Request queue, the queue will be created if it is null
     */
    public RequestQueue getRequestQueue() {
        // lazy initialize the request queue, the queue instance will be
        // created when it is accessed for the first time
        if (mRequestQueue == null) {
            // Create the request queue
            mRequestQueue = VolleyToolboxExtension.newRequestQueue(getApplicationContext());
        }

        return mRequestQueue;
    }

You could also use Retrofit instead of Volley, since Square released the 2.1 version of this library that supports TLS version configuration:

http://square.github.io/retrofit/

like image 92
crubio Avatar answered Nov 17 '22 17:11

crubio