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 android-developers+unsubscr...@googlegroups.com.
To post to this group, send email to android-developers@googlegroups.com.
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