Tracking openssl-1.0.1

Bug: 6168278

Change-Id: I240d2cbc91f616fd486efc5203e2221c9896d90f
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
index e43324b..0d10cf0 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
@@ -194,6 +194,8 @@
 
     private static final String SUPPORTED_PROTOCOL_SSLV3 = "SSLv3";
     private static final String SUPPORTED_PROTOCOL_TLSV1 = "TLSv1";
+    private static final String SUPPORTED_PROTOCOL_TLSV1_1 = "TLSv1.1";
+    private static final String SUPPORTED_PROTOCOL_TLSV1_2 = "TLSv1.2";
 
     public static final Map<String, String> OPENSSL_TO_STANDARD_CIPHER_SUITES
             = new HashMap<String, String>();
@@ -340,6 +342,8 @@
     public static final long SSL_OP_NO_COMPRESSION = 0x00020000L;
     public static final long SSL_OP_NO_SSLv3       = 0x02000000L;
     public static final long SSL_OP_NO_TLSv1       = 0x04000000L;
+    public static final long SSL_OP_NO_TLSv1_1     = 0x00000400L;
+    public static final long SSL_OP_NO_TLSv1_2     = 0x08000000L;
 
     public static native int SSL_CTX_new();
 
@@ -432,7 +436,11 @@
     public static native long SSL_clear_options(int ssl, long options);
 
     public static String[] getSupportedProtocols() {
-        return new String[] { SUPPORTED_PROTOCOL_SSLV3, SUPPORTED_PROTOCOL_TLSV1 };
+        return new String[] { SUPPORTED_PROTOCOL_SSLV3,
+                              SUPPORTED_PROTOCOL_TLSV1,
+                              SUPPORTED_PROTOCOL_TLSV1_1,
+                              SUPPORTED_PROTOCOL_TLSV1_2,
+        };
     }
 
     public static void setEnabledProtocols(int ssl, String[] protocols) {
@@ -440,7 +448,7 @@
         // openssl uses negative logic letting you disable protocols.
         // so first, assume we need to set all (disable all) and clear none (enable none).
         // in the loop, selectively move bits from set to clear (from disable to enable)
-        long optionsToSet = (SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
+        long optionsToSet = (SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2);
         long optionsToClear = 0;
         for (int i = 0; i < protocols.length; i++) {
             String protocol = protocols[i];
@@ -450,6 +458,12 @@
             } else if (protocol.equals(SUPPORTED_PROTOCOL_TLSV1)) {
                 optionsToSet &= ~SSL_OP_NO_TLSv1;
                 optionsToClear |= SSL_OP_NO_TLSv1;
+            } else if (protocol.equals(SUPPORTED_PROTOCOL_TLSV1_1)) {
+                optionsToSet &= ~SSL_OP_NO_TLSv1_1;
+                optionsToClear |= SSL_OP_NO_TLSv1_1;
+            } else if (protocol.equals(SUPPORTED_PROTOCOL_TLSV1_2)) {
+                optionsToSet &= ~SSL_OP_NO_TLSv1_2;
+                optionsToClear |= SSL_OP_NO_TLSv1_2;
             } else {
                 // error checked by checkEnabledProtocols
                 throw new IllegalStateException();
@@ -470,7 +484,9 @@
                 throw new IllegalArgumentException("protocols[" + i + "] == null");
             }
             if ((!protocol.equals(SUPPORTED_PROTOCOL_SSLV3))
-                    && (!protocol.equals(SUPPORTED_PROTOCOL_TLSV1))) {
+                    && (!protocol.equals(SUPPORTED_PROTOCOL_TLSV1))
+                    && (!protocol.equals(SUPPORTED_PROTOCOL_TLSV1_1))
+                    && (!protocol.equals(SUPPORTED_PROTOCOL_TLSV1_2))) {
                 throw new IllegalArgumentException("protocol " + protocol
                                                    + " is not supported");
             }
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLProvider.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLProvider.java
index d112074..97753cf 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLProvider.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLProvider.java
@@ -29,6 +29,8 @@
         put("SSLContext.SSLv3", OpenSSLContextImpl.class.getName());
         put("SSLContext.TLS", OpenSSLContextImpl.class.getName());
         put("SSLContext.TLSv1", OpenSSLContextImpl.class.getName());
+        put("SSLContext.TLSv1.1", OpenSSLContextImpl.class.getName());
+        put("SSLContext.TLSv1.2", OpenSSLContextImpl.class.getName());
         put("SSLContext.Default", DefaultSSLContextImpl.class.getName());
 
         // Message Digests
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java
index 20219e0..841c31c 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java
@@ -27,9 +27,6 @@
 
 /**
  * OpenSSL-based implementation of server sockets.
- *
- * This class only supports SSLv3 and TLSv1. This should be documented elsewhere
- * later, for example in the package.html or a separate reference document.
  */
 public class OpenSSLServerSocketImpl extends javax.net.ssl.SSLServerSocket {
     private final SSLParametersImpl sslParameters;
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
index d289449..49a6170 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
@@ -48,9 +48,6 @@
 /**
  * Implementation of the class OpenSSLSocketImpl based on OpenSSL.
  * <p>
- * This class only supports SSLv3 and TLSv1. This should be documented elsewhere
- * later, for example in the package.html or a separate reference document.
- * <p>
  * Extensions to SSLSocket include:
  * <ul>
  * <li>handshake timeout
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLRecordProtocol.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLRecordProtocol.java
index abec7d1..e9f77f7 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLRecordProtocol.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLRecordProtocol.java
@@ -442,7 +442,7 @@
     /**
      * Sets up the SSL version used in this connection.
      * This method is calling from the handshake protocol after
-     * it becomes known witch protocol version will be used.
+     * it becomes known which protocol version will be used.
      * @param   ver:    byte[]
      * @return
      */
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java
index b6a65b4..613e671 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java
@@ -330,11 +330,17 @@
                        "HANDSHAKE FAILURE. Incorrect client hello message");
         }
 
+        byte[] server_version = clientHello.client_version;
         if (!ProtocolVersion.isSupported(clientHello.client_version)) {
-            fatalAlert(AlertProtocol.PROTOCOL_VERSION,
-                       "PROTOCOL VERSION. Unsupported client version "
-                       + clientHello.client_version[0]
-                       + clientHello.client_version[1]);
+            if (clientHello.client_version[0] >= 3) {
+                // Protocol from the future, admit that the newest thing we know is TLSv1
+                server_version = ProtocolVersion.TLSv1.version;
+            } else {
+                fatalAlert(AlertProtocol.PROTOCOL_VERSION,
+                           "PROTOCOL VERSION. Unsupported client version "
+                           + clientHello.client_version[0]
+                           + clientHello.client_version[1]);
+            }
         }
 
         isResuming = false;
@@ -404,13 +410,13 @@
             }
         }
 
-        recordProtocol.setVersion(clientHello.client_version);
-        session.protocol = ProtocolVersion.getByVersion(clientHello.client_version);
+        recordProtocol.setVersion(server_version);
+        session.protocol = ProtocolVersion.getByVersion(server_version);
         session.clientRandom = clientHello.random;
 
         // create server hello message
         serverHello = new ServerHello(parameters.getSecureRandom(),
-                clientHello.client_version,
+                server_version,
                 session.getId(), cipher_suite, (byte) 0); //CompressionMethod.null
         session.serverRandom = serverHello.random;
         send(serverHello);
diff --git a/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp b/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
index c4c796a..aca3269 100644
--- a/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
+++ b/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
@@ -2368,6 +2368,8 @@
             break;
         case SSL3_VERSION:
         case TLS1_VERSION:
+        case TLS1_1_VERSION:
+        case TLS1_2_VERSION:
         case DTLS1_VERSION:
             ctype = ssl->s3->tmp.ctype;
             ctype_num = ssl->s3->tmp.ctype_num;
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index 0c1719c..04cd045 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -449,7 +449,7 @@
 
         RecordedRequest request = server.takeRequest();
         assertEquals("GET /foo HTTP/1.1", request.getRequestLine());
-        assertEquals("TLSv1", request.getSslProtocol());
+        assertEquals("TLSv1.2", request.getSslProtocol());
     }
 
     public void testConnectViaHttpsReusingConnections() throws IOException, InterruptedException {
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
index 5e91dc1..e3ae16f 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
@@ -166,7 +166,8 @@
         TestSSLContext c = TestSSLContext.create();
         SSLEngine e = c.clientContext.createSSLEngine();
         String[] protocols = e.getSupportedProtocols();
-        StandardNames.assertSupportedProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
+        StandardNames.assertSupportedProtocols(StandardNames.SSL_SOCKET_PROTOCOLS_SSLENGINE,
+                                               protocols);
         assertNotSame(protocols, e.getSupportedProtocols());
         c.close();
     }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java
index c516f67..e18b328 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java
@@ -691,7 +691,7 @@
             trustManagers = TestTrustManager.wrap(trustManagers);
         }
 
-        SSLContext ctx = SSLContext.getInstance("TLSv1");
+        SSLContext ctx = SSLContext.getInstance("TLSv1.2");
         ctx.init(keyManagers, trustManagers, null);
         return ctx;
     }
diff --git a/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java b/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java
index 934bd6f..e964940 100644
--- a/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java
+++ b/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java
@@ -161,6 +161,8 @@
         assertTrue((NativeCrypto.SSL_get_options(s) & 0x01000000L) != 0); // SSL_OP_NO_SSLv2
         assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0);
         assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1) == 0);
+        assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1_1) == 0);
+        assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1_2) == 0);
 
         int s2 = NativeCrypto.SSL_new(c);
         assertTrue(s != s2);
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java b/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java
index ec23cae..2b98182 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java
+++ b/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java
@@ -179,7 +179,7 @@
      * javax.net.ssl.SSLSession#getProtocol()
      */
     public void test_getProtocol() {
-        assertEquals("TLSv1", clientSession.getProtocol());
+        assertEquals("TLSv1.2", clientSession.getProtocol());
     }
 
     /**
diff --git a/support/src/test/java/libcore/java/security/StandardNames.java b/support/src/test/java/libcore/java/security/StandardNames.java
index 12f8539..e8b29e4 100644
--- a/support/src/test/java/libcore/java/security/StandardNames.java
+++ b/support/src/test/java/libcore/java/security/StandardNames.java
@@ -172,6 +172,8 @@
         provide("Policy", "JavaPolicy");
         provide("SSLContext", "SSLv3");
         provide("SSLContext", "TLSv1");
+        provide("SSLContext", "TLSv1.1");
+        provide("SSLContext", "TLSv1.2");
         provide("SecretKeyFactory", "DES");
         provide("SecretKeyFactory", "DESede");
         provide("SecretKeyFactory", "PBEWithMD5AndDES");
@@ -448,7 +450,9 @@
         // "SSLv2",
         "SSLv3",
         "TLS",
-        "TLSv1"));
+        "TLSv1",
+        "TLSv1.1",
+        "TLSv1.2"));
     public static final String SSL_CONTEXT_PROTOCOL_DEFAULT = "TLS";
 
     public static final Set<String> KEY_TYPES = new HashSet<String>(Arrays.asList(
@@ -464,7 +468,9 @@
     public static final Set<String> SSL_SOCKET_PROTOCOLS = new HashSet<String>(Arrays.asList(
         // "SSLv2",
         "SSLv3",
-        "TLSv1"));
+        "TLSv1",
+        "TLSv1.1",
+        "TLSv1.2"));
     static {
         if (IS_RI) {
             /* Even though we use OpenSSL's SSLv23_method which
@@ -474,9 +480,15 @@
              * do to disable general use of SSLv2.
              */
             SSL_SOCKET_PROTOCOLS.add("SSLv2Hello");
+        }
+    }
 
-            SSL_SOCKET_PROTOCOLS.add("TLSv1.1");
-            SSL_SOCKET_PROTOCOLS.add("TLSv1.2");
+    public static final Set<String> SSL_SOCKET_PROTOCOLS_SSLENGINE = new HashSet<String>(SSL_SOCKET_PROTOCOLS);
+    static {
+        // No TLSv1.1 or TLSv1.2 support on SSLEngine based provider
+        if (!IS_RI) {
+            SSL_SOCKET_PROTOCOLS_SSLENGINE.remove("TLSv1.1");
+            SSL_SOCKET_PROTOCOLS_SSLENGINE.remove("TLSv1.2");
         }
     }
 
@@ -798,7 +810,7 @@
         assertTrue(protocols.length != 0);
 
         // Make sure all protocols names are expected
-        Set remainingProtocols = new HashSet<String>(StandardNames.SSL_SOCKET_PROTOCOLS);
+        Set remainingProtocols = new HashSet<String>(expected);
         Set unknownProtocols = new HashSet<String>();
         for (String protocol : protocols) {
             if (!remainingProtocols.remove(protocol)) {
diff --git a/support/src/test/java/libcore/java/security/TestKeyStore.java b/support/src/test/java/libcore/java/security/TestKeyStore.java
index 30e40fb..e24ee78 100644
--- a/support/src/test/java/libcore/java/security/TestKeyStore.java
+++ b/support/src/test/java/libcore/java/security/TestKeyStore.java
@@ -387,7 +387,8 @@
                 // 1.) we make the keys
                 int keySize;
                 if (keyAlgorithm.equals("RSA")) {
-                    keySize = StandardNames.IS_RI ? 1024 : 512; // 512 breaks SSL_RSA_EXPORT_* on RI
+                    // 512 breaks SSL_RSA_EXPORT_* on RI and TLS_ECDHE_RSA_WITH_RC4_128_SHA for us
+                    keySize =  1024;
                 } else if (keyAlgorithm.equals("DSA")) {
                     keySize = 512;
                 } else if (keyAlgorithm.equals("EC")) {