Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SSLSocket via another SSLSocket

Tags:

I'm trying to create an SSLSocket on top of another SSLSocket in an Android app. The lower connection is an SSL-secured connection to a Secure Web Proxy (HTTP proxy over SSL), the upper connection is for HTTP over SSL (HTTPS).

For this, I'm using SSLSocketFactory's createSocket() function that allows to pass an existing Socket over which to run the SSL connection like this:

private Socket doSSLHandshake(Socket socket, String host, int port) throws IOException {     TrustManager[] trustAllCerts = new TrustManager[]{             new X509TrustManager(){                 public X509Certificate[] getAcceptedIssuers(){ return null; }                 public void checkClientTrusted(X509Certificate[] certs, String authType) {}                 public void checkServerTrusted(X509Certificate[] certs, String authType) {}             }     };      try {         SSLContext sslContext = SSLContext.getInstance("SSL");         sslContext.init(null, trustAllCerts, new SecureRandom());         SSLSocket sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(socket, host, port, true);         sslSocket.setEnabledProtocols(sslSocket.getSupportedProtocols());         sslSocket.setEnableSessionCreation(true);         sslSocket.startHandshake();         return sslSocket;     } catch (KeyManagementException | NoSuchAlgorithmException e) {         throw new IOException("Could not do handshake: " + e);     } } 

This code is working fine when the underlying socket is a normal tcp Socket, but when I use as underlying socket an SSLSocket that has been created using the above code before, the handshake fails with the following exception:

javax.net.ssl.SSLHandshakeException: Handshake failed     at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:429)     at com.myapp.MyThreadClass.doSSLHandshake(MyThreadClass.java:148)     at com.myapp.MyThreadClass.run(MyThreadClass.java:254) Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x7374d56e80: Failure in SSL library, usually a protocol error     error:100000e3:SSL routines:OPENSSL_internal:UNKNOWN_ALERT_TYPE (external/boringssl/src/ssl/s3_pkt.c:618 0x738418ce7e:0x00000000)     at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)     at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)     ... 2 more 

I'm testing on Android 7.1.1. The app is targeting SDK level 23.

  • What could I be doing wrong?
  • How could I further debug the issue?
  • Does anyone have a working example of an SSLSocket going over another SSLSocket on a recent Android version?

Any help is greatly appreciated!


Update: The very same code works in JRE 1.8 on a Mac, but not on Android.


Update 2: Conceptually, these are the steps the connection goes through:

  1. From the Android app, make a connection to the Secure Proxy server (Socket)
  2. Do an SSL/TLS handshake with the Proxy server (SSLSocket over Socket)
  3. Via the SSLSocket, send the CONNECT message to the Proxy server
  4. Proxy connects to destination (https) server and only copies bytes from now on
  5. Do an SSL/TLS handshake with the destination (https) server (SSLSocket over SSLSocket over Socket)
  6. Send the GET message to the destination server and read response

The problem arises in step 5, when doing the handshake on an SSLSocket that goes over an SSLSocket (that goes over a Socket).


Update 3: I have now opened a GitHub repo with a sample project and tcpdumps: https://github.com/FD-/SSLviaSSL


Note: I have found and read a question with very similar title, but it did not contain much useful help unfortunately.

like image 635
FD_ Avatar asked Feb 06 '17 22:02

FD_


People also ask

What is SSLSocket in java?

SSLSocket class is a subclass of the standard Java™ java. net. Socket class. It supports all of the standard socket methods and adds additional methods specific to secure sockets. Instances of this class encapsulate the SSLContext under which they were created.

What is SSLContext in Java?

SSLContext is an engine class for an implementation of a secure socket protocol. An instance of this class acts as a factory for SSL socket factories and SSL engines. An SSLContext holds all of the state information shared across all objects created under that context.


1 Answers

I don't think you're doing anything wrong. It looks like there's a bug in the protocol negotiation during your second handshake. A good candidate would be failing in an NPN TLS handshake extension.

Take a look at your protocols in this call: sslSocket.setEnabledProtocols(sslSocket.getSupportedProtocols());

You can walk through the listed protocols and try them individually. See if you can lock down what's failing and whether you need that specific protocol or extension supported.

like image 52
Hod Avatar answered Sep 27 '22 15:09

Hod