@Override
  public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
      throws IOException, UnknownHostException {

    SSLCertificateSocketFactory sslSocketFactory =
        (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(0);
    SSLSocket ssl = (SSLSocket) sslSocketFactory.createSocket(InetAddress.getByName(host), port);

    // enable TLSv1.1/1.2 if available
    // (see https://github.com/rfc2822/davdroid/issues/229)
    ssl.setEnabledProtocols(ssl.getSupportedProtocols());

    // set up SNI before the handshake
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
      Log.i("SNISocketFactory", "Setting SNI hostname");
      sslSocketFactory.setHostname(ssl, host);
    } else {
      Log.d(
          "SNISocketFactory", "No documented SNI support on Android <4.2, trying with reflection");
      try {
        java.lang.reflect.Method setHostnameMethod =
            ssl.getClass().getMethod("setHostname", String.class);
        setHostnameMethod.invoke(ssl, host);
      } catch (Exception e) {
        Log.w("SNISocketFactory", "SNI not useable", e);
      }
    }
    return ssl;
  }
Exemple #2
0
 private static void printSocketInfo(SSLSocket s) {
   LOGGER.info("Socket class: " + s.getClass());
   LOGGER.info("   Remote address = " + s.getInetAddress().toString());
   LOGGER.info("   Remote port = " + s.getPort());
   LOGGER.info("   Local socket address = " + s.getLocalSocketAddress().toString());
   LOGGER.info("   Local address = " + s.getLocalAddress().toString());
   LOGGER.info("   Local port = " + s.getLocalPort());
   LOGGER.info("   Need client authentication = " + s.getNeedClientAuth());
   SSLSession ss = s.getSession();
   LOGGER.info("   Cipher suite = " + ss.getCipherSuite());
   LOGGER.info("   Protocol = " + ss.getProtocol());
 }
  @Override
  public Socket createSocket(Socket plainSocket, String host, int port, boolean autoClose)
      throws IOException {
    String peerHost = this.conn.getRequestProperty("Host");
    if (peerHost == null) peerHost = host;
    Log.i(TAG, "customized createSocket. host: " + peerHost);
    InetAddress address = plainSocket.getInetAddress();
    if (autoClose) {
      // we don't need the plainSocket
      plainSocket.close();
    }
    // create and connect SSL socket, but don't do hostname/certificate verification yet
    SSLCertificateSocketFactory sslSocketFactory =
        (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(0);
    SSLSocket ssl = (SSLSocket) sslSocketFactory.createSocket(address, port);

    // enable TLSv1.1/1.2 if available
    ssl.setEnabledProtocols(ssl.getSupportedProtocols());

    // set up SNI before the handshake
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
      Log.i(TAG, "Setting SNI hostname");
      sslSocketFactory.setHostname(ssl, peerHost);
    } else {
      Log.d(TAG, "No documented SNI support on Android <4.2, trying with reflection");
      try {
        java.lang.reflect.Method setHostnameMethod =
            ssl.getClass().getMethod("setHostname", String.class);
        setHostnameMethod.invoke(ssl, peerHost);
      } catch (Exception e) {
        Log.w(TAG, "SNI not useable", e);
      }
    }

    // verify hostname and certificate
    SSLSession session = ssl.getSession();

    if (!hostnameVerifier.verify(peerHost, session))
      throw new SSLPeerUnverifiedException("Cannot verify hostname: " + peerHost);

    Log.i(
        TAG,
        "Established "
            + session.getProtocol()
            + " connection with "
            + session.getPeerHost()
            + " using "
            + session.getCipherSuite());

    return ssl;
  }
 @TargetApi(VERSION_CODES_JELLY_BEAN_MR1)
 private void setSniHostname(SSLSocket socket, String hostName) {
   // set SNI host name
   if (Build.VERSION.SDK_INT >= VERSION_CODES_JELLY_BEAN_MR1) {
     Log.d(TAG, "Using documented SNI with host name " + hostName);
     sslSocketFactory.setHostname(socket, hostName);
   } else {
     Log.d(
         TAG,
         "No documented SNI support on Android <4.2, trying reflection method with host name "
             + hostName);
     try {
       final Method setHostnameMethod = socket.getClass().getMethod("setHostname", String.class);
       setHostnameMethod.invoke(socket, hostName);
     } catch (Exception e) {
       Log.w(TAG, "SNI not usable", e);
     }
   }
 }
  @SuppressLint("NewApi")
  private Socket enableSNI(SSLSocket ssl, String host) throws SSLPeerUnverifiedException {
    // enable TLSv1.1/1.2 if available
    // (see https://github.com/rfc2822/davdroid/issues/229)
    ssl.setEnabledProtocols(ssl.getSupportedProtocols());

    // set up SNI before the handshake
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
      AppLog.i(T.API, "Setting SNI hostname");
      mFactory.setHostname(ssl, host);
    } else {
      AppLog.i(T.API, "No documented SNI support on Android <4.2, trying with reflection");
      try {
        java.lang.reflect.Method setHostnameMethod =
            ssl.getClass().getMethod("setHostname", String.class);
        setHostnameMethod.invoke(ssl, host);
      } catch (Exception e) {
        AppLog.e(T.API, "SNI not useable", e);
      }
    }

    // verify hostname and certificate
    SSLSession session = ssl.getSession();
    if (!mHostnameVerifier.verify(host, session)) {
      throw new SSLPeerUnverifiedException("Cannot verify hostname: " + host);
    }

    AppLog.i(
        T.API,
        "Established "
            + session.getProtocol()
            + " connection with "
            + session.getPeerHost()
            + " using "
            + session.getCipherSuite());

    return ssl;
  }