Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

javax.net.ssl.SSLException on Android 4 #198

Closed
andsh opened this issue Oct 4, 2016 · 4 comments
Closed

javax.net.ssl.SSLException on Android 4 #198

andsh opened this issue Oct 4, 2016 · 4 comments
Labels
android bug Acknowledged bug which is seen in Upload Service, but it's caused by an underlying Android Bug
Milestone

Comments

@andsh
Copy link

andsh commented Oct 4, 2016

Android Upload Service version: 3.0.3
Android version and API version: 4.1.2 API 16
HTTP stack (e.g. HurlStack or OkHttpStack): standard Android

What did you expect?

My application worked well on all modern phones

What happened instead?

On this old phone I get different errors
error one:
Write error: ssl=0x4da61008: I/O error during system call, Broken pipe
10-04 19:06:07.919 5951-5951/bg.motolife.app W/System.err: javax.net.ssl.SSLException: Write error: ssl=0x4da61008: I/O error during system call, Broken pipe
10-04 19:06:07.939 5951-5951/bg.motolife.app W/System.err: at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_write(Native Method)
10-04 19:06:07.939 5951-5951/bg.motolife.app W/System.err: at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:693)
10-04 19:06:07.939 5951-5951/bg.motolife.app W/System.err: at java.io.BufferedOutputStream.flushInternal(BufferedOutputStream.java:185)
10-04 19:06:07.939 5951-5951/bg.motolife.app W/System.err: at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:85)
10-04 19:06:07.939 5951-5951/bg.motolife.app W/System.err: at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:810)
10-04 19:06:07.939 5951-5951/bg.motolife.app W/System.err: at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:274)
10-04 19:06:07.939 5951-5951/bg.motolife.app W/System.err: at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:486)
10-04 19:06:07.939 5951-5951/bg.motolife.app W/System.err: at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:134)
10-04 19:06:07.939 5951-5951/bg.motolife.app W/System.err: at net.gotev.uploadservice.http.impl.HurlStackConnection.getServerResponseCode(HurlStackConnection.java:89)
10-04 19:06:07.939 5951-5951/bg.motolife.app W/System.err: at net.gotev.uploadservice.HttpUploadTask.upload(HttpUploadTask.java:72)
10-04 19:06:07.939 5951-5951/bg.motolife.app W/System.err: at net.gotev.uploadservice.UploadTask.run(UploadTask.java:139)
10-04 19:06:07.939 5951-5951/bg.motolife.app W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
10-04 19:06:07.939 5951-5951/bg.motolife.app W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
10-04 19:06:07.939 5951-5951/bg.motolife.app W/System.err: at java.lang.Thread.run(Thread.java:856)

Error two:
10-04 19:42:00.359 17898-17898/bg.motolife.app E/gotev: onError null
10-04 19:42:00.359 17898-17898/bg.motolife.app W/System.err: java.io.EOFException
10-04 19:42:00.369 17898-17898/bg.motolife.app W/System.err: at libcore.io.Streams.readAsciiLine(Streams.java:203)
10-04 19:42:00.369 17898-17898/bg.motolife.app W/System.err: at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:560)
10-04 19:42:00.369 17898-17898/bg.motolife.app W/System.err: at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:813)
10-04 19:42:00.369 17898-17898/bg.motolife.app W/System.err: at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:274)
10-04 19:42:00.379 17898-17898/bg.motolife.app W/System.err: at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:486)
10-04 19:42:00.379 17898-17898/bg.motolife.app W/System.err: at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:134)
10-04 19:42:00.379 17898-17898/bg.motolife.app W/System.err: at net.gotev.uploadservice.http.impl.HurlStackConnection.getServerResponseCode(HurlStackConnection.java:89)
10-04 19:42:00.379 17898-17898/bg.motolife.app W/System.err: at net.gotev.uploadservice.HttpUploadTask.upload(HttpUploadTask.java:72)
10-04 19:42:00.379 17898-17898/bg.motolife.app W/System.err: at net.gotev.uploadservice.UploadTask.run(UploadTask.java:139)
10-04 19:42:00.379 17898-17898/bg.motolife.app W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
10-04 19:42:00.379 17898-17898/bg.motolife.app W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
10-04 19:42:00.379 17898-17898/bg.motolife.app W/System.err: at java.lang.Thread.run(Thread.java:856)

Library initialization code:

public void onCreate() {
super.onCreate();
mInstance = this;
Fresco.initialize(this);
net.gotev.uploadservice.UploadService.NAMESPACE = bg.motolife.app.BuildConfig.APPLICATION_ID;
org.acra.ACRA.getErrorReporter().putCustomData("mlserial", Build.SERIAL);
PrefManager pref;
pref = new PrefManager(getApplicationContext());
org.acra.ACRA.getErrorReporter().putCustomData("mlphone", pref.getMobileNumber());
/FBL if (!org.acra.ACRA.isACRASenderServiceProcess()) {
com.facebook.FacebookSdk.sdkInitialize(getApplicationContext());
com.facebook.appevents.AppEventsLogger.activateApp(this);
}
/
}

Request code:

final String uploadId =
new net.gotev.uploadservice.MultipartUploadRequest(getApplicationContext(), "https://www.xxx.xxx/post_avatar.php")
.setCustomUserAgent("MotolifeBG " + System.getProperty("http.agent"))
.addFileToUpload(RegistrationFaceBook.this.getExternalFilesDir(null) + "/myavatardir/tmpavatar.jpg", "avatar")
.addParameter("phone",pref.getMobileNumber())
.addParameter("mltoken",pref.getMlToken())
.setDelegate(this).startUpload();

Where have you added the request code?

Activity

LogCat output

10-04 19:42:00.039 17898-17898/bg.motolife.app E/gotev: uploadId=6d4e1c7e-579b-4ad2-b123-9badc18b69dc
10-04 19:42:00.049 17898-21517/bg.motolife.app V/FA: Activity resumed, time: 4377682
10-04 19:42:00.119 17898-21895/bg.motolife.app I/dalvikvm: Could not find method java.net.HttpURLConnection.setFixedLengthStreamingMode, referenced from method net.gotev.uploadservice.http.impl.HurlStackConnection.setHeaders
10-04 19:42:00.119 17898-21895/bg.motolife.app W/dalvikvm: VFY: unable to resolve virtual method 44675: Ljava/net/HttpURLConnection;.setFixedLengthStreamingMode (J)V
10-04 19:42:00.119 17898-21895/bg.motolife.app D/dalvikvm: VFY: replacing opcode 0x6e at 0x000a
10-04 19:42:00.219 17898-17898/bg.motolife.app D/dalvikvm: WAIT_FOR_CONCURRENT_GC blocked 0ms
10-04 19:42:00.259 17898-17898/bg.motolife.app D/dalvikvm: GC_EXPLICIT freed 1935K, 23% free 15274K/19591K, paused 3ms+3ms, total 46ms
10-04 19:42:00.259 17898-17898/bg.motolife.app E/gotev: onProgress eltstr=0s elt=22 ratestr=0 bit/s prc=0 tb=31089 ub=105
10-04 19:42:00.269 17898-17898/bg.motolife.app D/dalvikvm: WAIT_FOR_CONCURRENT_GC blocked 0ms
10-04 19:42:00.319 17898-17898/bg.motolife.app D/dalvikvm: GC_EXPLICIT freed 5K, 23% free 15272K/19591K, paused 3ms+5ms, total 51ms
10-04 19:42:00.359 17898-17898/bg.motolife.app E/gotev: onError null
10-04 19:42:00.359 17898-17898/bg.motolife.app W/System.err: java.io.EOFException
10-04 19:42:00.369 17898-17898/bg.motolife.app W/System.err: at libcore.io.Streams.readAsciiLine(Streams.java:203)
10-04 19:42:00.369 17898-17898/bg.motolife.app W/System.err: at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:560)
10-04 19:42:00.369 17898-17898/bg.motolife.app W/System.err: at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:813)
10-04 19:42:00.369 17898-17898/bg.motolife.app W/System.err: at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:274)
10-04 19:42:00.379 17898-17898/bg.motolife.app W/System.err: at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:486)
10-04 19:42:00.379 17898-17898/bg.motolife.app W/System.err: at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:134)
10-04 19:42:00.379 17898-17898/bg.motolife.app W/System.err: at net.gotev.uploadservice.http.impl.HurlStackConnection.getServerResponseCode(HurlStackConnection.java:89)
10-04 19:42:00.379 17898-17898/bg.motolife.app W/System.err: at net.gotev.uploadservice.HttpUploadTask.upload(HttpUploadTask.java:72)
10-04 19:42:00.379 17898-17898/bg.motolife.app W/System.err: at net.gotev.uploadservice.UploadTask.run(UploadTask.java:139)
10-04 19:42:00.379 17898-17898/bg.motolife.app W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
10-04 19:42:00.379 17898-17898/bg.motolife.app W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
10-04 19:42:00.379 17898-17898/bg.motolife.app W/System.err: at java.lang.Thread.run(Thread.java:856)

Server side

PHP on Apache

Server log (if applicable)

No server activity from this old phone

Additional info

On Android 5.0 and 6.0 everything is ok

@gotev
Copy link
Owner

gotev commented Oct 6, 2016

This happens almost surely because your server certificate uses TLS 1.2, which is not enabled by default on Android API < 21. It's an Android problem, but there is a solution to it.

First of all, I recommend you to switch to the OkHttp stack (which will be the default HTTP stack from 3.1+). Next, copy Tls12SocketFactory.java into your project. Then, to enable TLS 1.2, you can do like this in your initialization code:

public class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();

        UploadService.HTTP_STACK = new OkHttpStack(getHttpClient(this));
    }

    private static OkHttpClient getHttpClient(Context context) {
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .followRedirects(true)
                .followSslRedirects(true)
                .retryOnConnectionFailure(true)
                .connectTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .cache(null);

        return enableTls12OnPreLollipop(clientBuilder).build();
    }

    /**
     * Enables TLS 1.2 on Pre-Lollipop devices (16 >= Android API < 20)
     * Check: https://github.com/square/okhttp/issues/2372#issuecomment-244807676
     * @param client OkHttpClient.Builder on which to apply the patch
     * @return OkHttpClient.Builder with the patch applied
     */
    private static OkHttpClient.Builder enableTls12OnPreLollipop(OkHttpClient.Builder client) {
        // the problem sill persists on some samsung devices with API 21, so it's necessary
        // to apply the patch till API 21
        if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 22) {
            try {
                SSLContext sc = SSLContext.getInstance("TLSv1.2");
                sc.init(null, null, null);
                client.sslSocketFactory(new Tls12SocketFactory(sc.getSocketFactory()));

                ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
                        .tlsVersions(TlsVersion.TLS_1_2)
                        .build();

                List<ConnectionSpec> specs =  new ArrayList<>();
                specs.add(cs);
                specs.add(ConnectionSpec.COMPATIBLE_TLS);
                specs.add(ConnectionSpec.CLEARTEXT);

                client.connectionSpecs(specs);
            } catch (Throwable exc) {
                Log.e("OkHttp", "Error while setting TLS 1.2", exc);
            }
        }

        return client;
    }
}

@gotev gotev changed the title Write error: ssl=0x4da61008: I/O error during system call, Broken pipe javax.net.ssl.SSLException on Android 4 Oct 6, 2016
@gotev gotev added android bug Acknowledged bug which is seen in Upload Service, but it's caused by an underlying Android Bug workaround available labels Oct 6, 2016
@andsh
Copy link
Author

andsh commented Oct 6, 2016

Thank you for this workaround.
Can you please direct me, how to switch to the OkHttp stack?

@gotev
Copy link
Owner

gotev commented Oct 6, 2016

Head to the setup Wiki page

@andsh
Copy link
Author

andsh commented Oct 6, 2016

Thank you
This solution works perfectly

@gotev gotev closed this as completed Oct 6, 2016
@gotev gotev added this to the 3.1 milestone Oct 6, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
android bug Acknowledged bug which is seen in Upload Service, but it's caused by an underlying Android Bug
Projects
None yet
Development

No branches or pull requests

2 participants