You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2015/01/01 19:56:15 UTC

svn commit: r1648918 - /httpcomponents/httpclient-android/branches/4.3.5-android/src/main/java/org/apache/http/conn/ssl/SSLConnectionSocketFactory.java

Author: olegk
Date: Thu Jan  1 18:56:15 2015
New Revision: 1648918

URL: http://svn.apache.org/r1648918
Log:
Disable all versions of SSL protocol by default; SSL session debug logs

Modified:
    httpcomponents/httpclient-android/branches/4.3.5-android/src/main/java/org/apache/http/conn/ssl/SSLConnectionSocketFactory.java

Modified: httpcomponents/httpclient-android/branches/4.3.5-android/src/main/java/org/apache/http/conn/ssl/SSLConnectionSocketFactory.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient-android/branches/4.3.5-android/src/main/java/org/apache/http/conn/ssl/SSLConnectionSocketFactory.java?rev=1648918&r1=1648917&r2=1648918&view=diff
==============================================================================
--- httpcomponents/httpclient-android/branches/4.3.5-android/src/main/java/org/apache/http/conn/ssl/SSLConnectionSocketFactory.java (original)
+++ httpcomponents/httpclient-android/branches/4.3.5-android/src/main/java/org/apache/http/conn/ssl/SSLConnectionSocketFactory.java Thu Jan  1 18:56:15 2015
@@ -40,13 +40,22 @@ import org.apache.http.util.TextUtils;
 
 import javax.net.SocketFactory;
 import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
+import javax.security.auth.x500.X500Principal;
+
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.InetSocketAddress;
 import java.net.Socket;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
 
 /**
  * Layered socket factory for TLS/SSL connections.
@@ -248,6 +257,9 @@ public class SSLConnectionSocketFactory
             if (connectTimeout > 0 && sock.getSoTimeout() == 0) {
                 sock.setSoTimeout(connectTimeout);
             }
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "Connecting socket to " + remoteAddress + " with timeout " + connectTimeout);
+            }
             sock.connect(remoteAddress, connectTimeout);
         } catch (final IOException ex) {
             try {
@@ -259,6 +271,9 @@ public class SSLConnectionSocketFactory
         // Setup SSL layering if necessary
         if (sock instanceof SSLSocket) {
             final SSLSocket sslsock = (SSLSocket) sock;
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "Starting handshake");
+            }
             sslsock.startHandshake();
             verifyHostname(sslsock, host.getHostName());
             return sock;
@@ -280,10 +295,25 @@ public class SSLConnectionSocketFactory
                 true);
         if (supportedProtocols != null) {
             sslsock.setEnabledProtocols(supportedProtocols);
+        } else {
+            // If supported protocols are not explicitly set, remove all SSL protocol versions
+            final String[] allProtocols = sslsock.getSupportedProtocols();
+            final List<String> enabledProtocols = new ArrayList<String>(allProtocols.length);
+            for (String protocol: allProtocols) {
+                if (!protocol.startsWith("SSL")) {
+                    enabledProtocols.add(protocol);
+                }
+            }
+            sslsock.setEnabledProtocols(enabledProtocols.toArray(new String[enabledProtocols.size()]));
         }
         if (supportedCipherSuites != null) {
             sslsock.setEnabledCipherSuites(supportedCipherSuites);
         }
+
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            Log.d(TAG, "Enabled protocols: " + Arrays.asList(sslsock.getEnabledProtocols()));
+            Log.d(TAG, "Enabled cipher suites:" + Arrays.asList(sslsock.getEnabledCipherSuites()));
+        }
         prepareSocket(sslsock);
 
         // Android specific code to enable SNI
@@ -302,6 +332,9 @@ public class SSLConnectionSocketFactory
         }
         // End of Android specific code
 
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            Log.d(TAG, "Starting handshake");
+        }
         sslsock.startHandshake();
         verifyHostname(sslsock, target);
         return sslsock;
@@ -313,6 +346,41 @@ public class SSLConnectionSocketFactory
 
     private void verifyHostname(final SSLSocket sslsock, final String hostname) throws IOException {
         try {
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                try {
+                    final SSLSession session = sslsock.getSession();
+                    Log.d(TAG, "Secure session established");
+                    Log.d(TAG, " negotiated protocol: " + session.getProtocol());
+                    Log.d(TAG, " negotiated cipher suite: " + session.getCipherSuite());
+
+                    final Certificate[] certs = session.getPeerCertificates();
+                    final X509Certificate x509 = (X509Certificate) certs[0];
+                    final X500Principal peer = x509.getSubjectX500Principal();
+
+                    Log.d(TAG, " peer principal: " + peer.toString());
+                    final Collection<List<?>> altNames1 = x509.getSubjectAlternativeNames();
+                    if (altNames1 != null) {
+                        for (final List<?> aC : altNames1) {
+                            if (!aC.isEmpty()) {
+                                Log.d(TAG, " peer alternative name: " + aC.get(1));
+                            }
+                        }
+                    }
+
+                    final X500Principal issuer = x509.getIssuerX500Principal();
+                    Log.d(TAG, " issuer principal: " + issuer.toString());
+                    final Collection<List<?>> altNames2 = x509.getIssuerAlternativeNames();
+                    if (altNames2 != null) {
+                        for (final List<?> aC : altNames2) {
+                            if (!aC.isEmpty()) {
+                                Log.d(TAG, " issuer alternative name: " + aC.get(1));
+                            }
+                        }
+                    }
+                } catch (Exception ignore) {
+                }
+            }
+
             this.hostnameVerifier.verify(hostname, sslsock);
             // verifyHostName() didn't blowup - good!
         } catch (final IOException iox) {