25

Hi I am working on android app in which I have integrated bigquery. I see sometimes we are getting a lot of SSL exceptions while inserting data to big query tables. I don't know how to handle this . Please help what exactly is the cause of this problem. Here is the same thread but no answer Bigquery SSL error while doing streaming insert api call

javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:946) ~[na:1.7.0_51]
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) ~[na:1.7.0_51]
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339) ~[na:1.7.0_51]
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323) ~[na:1.7.0_51]
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563) ~[na:1.7.0_51]
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) ~[na:1.7.0_51]
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1091) ~[na:1.7.0_51]
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250) ~[na:1.7.0_51]
    at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:77) ~[google-http-client-1.19.0.jar:1.19.0]
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:965) ~[google-http-client-1.19.0.jar:1.19.0]
    at com.google.api.client.googleapis.batch.BatchRequest.execute(BatchRequest.java:241) ~[google-api-client-1.19.1.jar:1.19.1]
    at com.livestream.analytics.datastorage.worker.InsertApiActor$$anonfun$2$$anonfun$4.apply(InsertApiActor.scala:131) ~[analytics-data-storage-worker_2.11-1.0.0.jar:1.0.0]
    at com.livestream.analytics.datastorage.worker.InsertApiActor$$anonfun$2$$anonfun$4.apply(InsertApiActor.scala:118) ~[analytics-data-storage-worker_2.11-1.0.0.jar:1.0.0]
    at com.livestream.analytics.common.store.bigquery.api.BigQueryApi$.withSyncClient(BigQueryApi.scala:71) ~[analytics-common_2.11-1.0.0.jar:1.0.0]
    at com.livestream.analytics.datastorage.worker.InsertApiActor$$anonfun$2.apply$mcV$sp(InsertApiActor.scala:118) ~[analytics-data-storage-worker_2.11-1.0.0.jar:1.0.0]
    at com.livestream.analytics.datastorage.worker.InsertApiActor$$anonfun$2.apply(InsertApiActor.scala:115) ~[analytics-data-storage-worker_2.11-1.0.0.jar:1.0.0]
    at com.livestream.analytics.datastorage.worker.InsertApiActor$$anonfun$2.apply(InsertApiActor.scala:115) ~[analytics-data-storage-worker_2.11-1.0.0.jar:1.0.0]
    at com.livestream.analytics.common.monitoring.Timer.time(Timer.scala:15) ~[analytics-common_2.11-1.0.0.jar:1.0.0]
    at com.livestream.analytics.datastorage.worker.InsertApiActor.com$livestream$analytics$datastorage$worker$InsertApiActor$$insertDataRowsToBigQueryTable(InsertApiActor.scala:115) [analytics-data-storage-worker_2.11-1.0.0.jar:1.0.0]
    at com.livestream.analytics.datastorage.worker.InsertApiActor$$anonfun$receive$1.applyOrElse(InsertApiActor.scala:80) [analytics-data-storage-worker_2.11-1.0.0.jar:1.0.0]
    at akka.actor.Actor$class.aroundReceive(Actor.scala:465) [akka-actor_2.11-2.3.9.jar:na]
    at com.livestream.analytics.datastorage.worker.InsertApiActor.aroundReceive(InsertApiActor.scala:54) [analytics-data-storage-worker_2.11-1.0.0.jar:1.0.0]
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516) [akka-actor_2.11-2.3.9.jar:na]
    at akka.actor.ActorCell.invoke(ActorCell.scala:487) [akka-actor_2.11-2.3.9.jar:na]
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:254) [akka-actor_2.11-2.3.9.jar:na]
    at akka.dispatch.Mailbox.run(Mailbox.scala:221) [akka-actor_2.11-2.3.9.jar:na]
    at akka.dispatch.Mailbox.exec(Mailbox.scala:231) [akka-actor_2.11-2.3.9.jar:na]
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) [scala-library-2.11.5.jar:na]
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) [scala-library-2.11.5.jar:na]
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [scala-library-2.11.5.jar:na]
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [scala-library-2.11.5.jar:na]
Caused by: java.io.EOFException: SSL peer shut down incorrectly
    at sun.security.ssl.InputRecord.read(InputRecord.java:482) ~[na:1.7.0_51]
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927) ~[na:1.7.0_51]
    ... 30 common frames omitted
Community
  • 1
  • 1
N Sharma
  • 33,489
  • 95
  • 256
  • 444
  • 1
    If you have a means to reliably reproduce this issue, and you have reason to believe it's not the fault of your application, you should report the issue with all code and stack-traces you can provide in the [public issue tracker for BigQuery](https://code.google.com/p/google-bigquery/issues/list). At that point it will be triaged by support engineers and addressed in proportion to its severity, number of people who starred the issue, and how new it is. – Nick Jun 25 '15 at 22:45
  • Did you manage to create a public issue tracker thread, or have you made any progress in debugging this? If the issue is completely opaque to you (and it seems there's nothing you can do, given `SSL peer shut down incorrectly`), then that's the best course of action to get this looked-at. Be sure to include as much relevant code or logs as you can. – Nick Jun 30 '15 at 17:50
  • I also faced this exception once. Then i resoled it by using volley api. if you want then i can share the code. – hitesh141 Jul 07 '15 at 09:15
  • @hitesh141 Please share – N Sharma Jul 08 '15 at 05:59
  • Do you get this problem while you're calling your web service? – Anshul Tyagi Jul 09 '15 at 03:22
  • When are you facing this problem then? – Anshul Tyagi Jul 09 '15 at 05:27
  • @Williams actually, I had this problem 2 days ago if you explain then I can solve it. – Anshul Tyagi Jul 09 '15 at 05:29
  • First you need to obtain the public certificate from the server you're trying to connect to. That can be done in a variety of ways, such as contacting the server admin and asking for it, using openssl to download it, or, since this appears to be an HTTP server, connecting to it with any browser, viewing the page's security info, and saving a copy of the certificate. (Google should be able to tell you exactly what to do for your specific browser.) Now that you have the certificate saved in a file – hitesh141 Jul 09 '15 at 06:00
  • I did all. I told sometimes it doesn't work not always that is weird. It looks like bug in big query jar files that is failing to communicate with google server. – N Sharma Jul 11 '15 at 06:10
  • Are you using a virtual machine? we experienced lots of the same error when it ran on a virtual machine. – foxwendy Aug 19 '15 at 13:58

2 Answers2

1

Probably the server is asking for a client certificate and you aren't providing one. The server will provide a list of trusted signers, and your client certificate needs to be signed by one of those. You can't use a self-signed certificate for the client unless you've made special arrangements with the server, i.e. imported your client certificate into its trusted certificate list. Your SSL client won't send a certificate if it can't find one, or if the one(s) that it finds don't have trusted signers.

It doesn't have anything to do with what the SSL connection was going to do after it was established, e.g. SQL queries, updates, etc.

user207421
  • 305,947
  • 44
  • 307
  • 483
0

If you are using (https) requests you need to add Security Certificate in your app. here is link how to add it.

http://stackoverflow.com/questions/4065379/how-to-create-a-bks-bouncycastle-format-java-keystore-that-contains-a-client-c

You can test if indeed security certificate is causing it, Add this class in your project.

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;


public class HttpsTrustManager implements X509TrustManager {

    private static TrustManager[] trustManagers;
    private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[]{};

    @Override
    public void checkClientTrusted(
            java.security.cert.X509Certificate[] x509Certificates, String s)
            throws java.security.cert.CertificateException {

    }

    @Override
    public void checkServerTrusted(
            java.security.cert.X509Certificate[] x509Certificates, String s)
            throws java.security.cert.CertificateException {

    }

    public boolean isClientTrusted(X509Certificate[] chain) {
        return true;
    }

    public boolean isServerTrusted(X509Certificate[] chain) {
        return true;
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return _AcceptedIssuers;
    }

    public static void allowAllSSL() {
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {

            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }

        });

        SSLContext context = null;
        if (trustManagers == null) {
            trustManagers = new TrustManager[]{new HttpsTrustManager()};
        }

        try {
            context = SSLContext.getInstance("TLS");
            context.init(null, trustManagers, new SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }

        HttpsURLConnection.setDefaultSSLSocketFactory(context
                .getSocketFactory());
    }

}

and call

 HttpsTrustManager.allowAllSSL();  // Allow all SSL connections

before an API call.

NOTE: This code skips verification and allows any certificate to work. This method should not be used for secure communication. This is just to check if Certificate authentication is causing the error.

iUK
  • 31
  • 8
  • 1
    This insecure code will not test whether the server is requesting a client certificate. – user207421 Mar 01 '16 at 00:21
  • If this question is about client certificates, then this line `context.init(null, trustManagers, new SecureRandom());` is definitely wrong; the `null` parameter is the `KeyManager` that can provide the client certificate. – EpicPandaForce May 27 '16 at 12:41