Hello everyone,

I encountered a android ssl issue. I want to developer a android app, it 
can connect https web site through TLS tunnel proxy, but I failed. I tried 
to use several version httpclient or java socked api. I got the same error, 
but I it works find on my PC.
I got the following error in android. I don't know why. Could you please 
help me?
I attached the source file and a tcpdump file. In tcpdump file frame 27 is 
the alert type.

javax.net.ssl.SSLHandshakeException: Handshake failed

03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: at 
com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:396)

03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: at 
com.jason.httpclientexample.SSLSocketClientWithTunneling.doIt(SSLSocketClientWithTunneling.java:96)

03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: at 
com.jason.httpclientexample.MainActivity.executeHttpRequest(MainActivity.java:100)

03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: at 
com.jason.httpclientexample.MainActivity.access$100(MainActivity.java:24)

03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: at 
com.jason.httpclientexample.MainActivity$2$1.run(MainActivity.java:61)

03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: at 
java.lang.Thread.run(Thread.java:818)

03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: 
Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: 
ssl=0x7fa87388a700: Failure in SSL library, usually a protocol error

03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: 
error:100c50f5:SSL routines:ssl3_read_bytes:UNKNOWN_ALERT_TYPE 
(external/boringssl/src/ssl/s3_pkt.c:980 0x7fa87bff2c9a:0x00000000)

03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: at 
com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)

03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: at 
com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:324)

03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: 
    ... 5 more



Thanks,

John


-- 
You received this message because you are subscribed to the Google Groups 
"Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/android-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/android-developers/048baa79-5f2a-476b-bda7-4ec0f2787974%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
package com.jason.httpclientexample;

/**
 * Created by jbai on 3/16/16.
 */

import java.net.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.io.*;
import javax.net.ssl.*;

public class SSLSocketClientWithTunneling {

    public static void main(String[] args) throws Exception {
        new SSLSocketClientWithTunneling().doIt("172.16.50.50", 443);
    }

    String tunnelHost;
    int tunnelPort;

    public void doIt(String host, int port) {
        try {

            /*
             * Let's setup the SSLContext first, as there's a lot of
             * computations to be done.  If the socket were created
             * before the SSLContext, the server/proxy might timeout
             * waiting for the client to actually send something.
             */

            X509TrustManager tm = new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                    // TODO Auto-generated method stub

                }
                public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                    // TODO Auto-generated method stub

                }
                public X509Certificate[] getAcceptedIssuers() {
                    // TODO Auto-generated method stub
                    return null;
                }
            };

            SSLContext ctx = SSLContext.getInstance("TLS");
            ctx.init(null, new TrustManager[]{tm}, null);

            SSLSocketFactory factory = ctx.getSocketFactory();

            /*
             * Set up a socket to do tunneling through the proxy.
             * Start it off as a regular socket, then layer SSL
             * over the top of it.
             */
            //tunnelHost = System.getProperty("https.proxyHost");
            //tunnelPort = Integer.getInteger("https.proxyPort").intValue();

            tunnelHost = "172.16.50.51";
            tunnelPort = 443;

            //Socket tunnel = new Socket(tunnelHost, tunnelPort);
            SSLSocket tunnel = (SSLSocket)factory.createSocket(tunnelHost, tunnelPort);
            doTunnelHandshake(tunnel, host, port);

            /*
             * Ok, let's overlay the tunnel socket with SSL.
             */
            SSLSocket socket = (SSLSocket)factory.createSocket(tunnel, host, port, true);

            /*
             * register a callback for handshaking completion event
             */
            socket.addHandshakeCompletedListener(
                    new HandshakeCompletedListener() {
                        public void handshakeCompleted(
                                HandshakeCompletedEvent event) {
                            System.out.println("Handshake finished!");
                            System.out.println(
                                    "\t CipherSuite:" + event.getCipherSuite());
                            System.out.println(
                                    "\t SessionId " + event.getSession());
                            System.out.println(
                                    "\t PeerHost " + event.getSession().getPeerHost());
                        }
                    }
            );

            /*
             * send http request
             *
             * See SSLSocketClient.java for more information about why
             * there is a forced handshake here when using PrintWriters.
             */
            socket.startHandshake();

            PrintWriter out = new PrintWriter(
                    new BufferedWriter(
                            new OutputStreamWriter(
                                    socket.getOutputStream())));

            out.println("GET / HTTP/1.0");
            out.println();
            out.flush();

            /*
             * Make sure there were no surprises
             */
            if (out.checkError())
                System.out.println(
                        "SSLSocketClient:  java.io.PrintWriter error");

            /* read response */
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(
                            socket.getInputStream()));

            String inputLine;

            while ((inputLine = in.readLine()) != null)
                System.out.println(inputLine);

            in.close();
            out.close();
            socket.close();
            tunnel.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * Tell our tunnel where we want to CONNECT, and look for the
     * right reply.  Throw IOException if anything goes wrong.
     */
    private void doTunnelHandshake(Socket tunnel, String host, int port)
            throws IOException
    {
        OutputStream out = tunnel.getOutputStream();
        String msg = "CONNECT " + host + ":" + port + " HTTP/1.1\n"
                + "User-Agent: "
                + "java"
                + "\r\n\r\n";
        byte b[];
        try {
            /*
             * We really do want ASCII7 -- the http protocol doesn't change
             * with locale.
             */
            b = msg.getBytes("ASCII7");
        } catch (UnsupportedEncodingException ignored) {
            /*
             * If ASCII7 isn't there, something serious is wrong, but
             * Paranoia Is Good (tm)
             */
            b = msg.getBytes();
        }
        out.write(b);
        out.flush();

        /*
         * We need to store the reply so we can create a detailed
         * error message to the user.
         */
        byte            reply[] = new byte[200];
        int             replyLen = 0;
        int             newlinesSeen = 0;
        boolean         headerDone = false;     /* Done on first newline */

        InputStream     in = tunnel.getInputStream();
        boolean         error = false;

        while (newlinesSeen < 2) {
            int i = in.read();
            if (i < 0) {
                throw new IOException("Unexpected EOF from proxy");
            }
            if (i == '\n') {
                headerDone = true;
                ++newlinesSeen;
            } else if (i != '\r') {
                newlinesSeen = 0;
                if (!headerDone && replyLen < reply.length) {
                    reply[replyLen++] = (byte) i;
                }
            }
        }

        /*
         * Converting the byte array to a string is slightly wasteful
         * in the case where the connection was successful, but it's
         * insignificant compared to the network overhead.
         */
        String replyStr;
        try {
            replyStr = new String(reply, 0, replyLen, "ASCII7");
        } catch (UnsupportedEncodingException ignored) {
            replyStr = new String(reply, 0, replyLen);
        }

        /* We asked for HTTP/1.0, so we should get that back */
        if (!replyStr.startsWith("HTTP/1.1 200")) {
            throw new IOException("Unable to tunnel through "
                    + tunnelHost + ":" + tunnelPort
                    + ".  Proxy returns \"" + replyStr + "\"");
        }

        /* tunneling Handshake was successful! */
    }
}

Attachment: 2.cap
Description: application/cap

Reply via email to