Merge "Merge "DO NOT MERGE: Remove StuckServer using backlog and tests relying on it" into marshmallow-cts-dev am: 244e7d3556  -s ours" into nougat-cts-dev
am: 8de6ec43d2  -s ours

Change-Id: If9f6c374d32052c73883c645791eace320328af2
diff --git a/benchmarks/src/benchmarks/regression/DateFormatBenchmark.java b/benchmarks/src/benchmarks/regression/DateFormatBenchmark.java
new file mode 100644
index 0000000..bd5bf1a
--- /dev/null
+++ b/benchmarks/src/benchmarks/regression/DateFormatBenchmark.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package benchmarks.regression;
+
+import com.google.caliper.BeforeExperiment;
+
+import java.text.DateFormat;
+import java.util.Locale;
+
+public final class DateFormatBenchmark {
+
+    private Locale locale1;
+    private Locale locale2;
+    private Locale locale3;
+    private Locale locale4;
+
+    @BeforeExperiment
+    protected void setUp() throws Exception {
+        locale1 = Locale.TAIWAN;
+        locale2 = Locale.GERMANY;
+        locale3 = Locale.FRANCE;
+        locale4 = Locale.ITALY;
+    }
+
+    public void timeGetDateTimeInstance(int reps) throws Exception {
+        for (int i = 0; i < reps; ++i) {
+            DateFormat.getDateTimeInstance();
+        }
+    }
+
+    public void timeGetDateTimeInstance_multiple(int reps) throws Exception {
+        for (int i = 0; i < reps; ++i) {
+            DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale1);
+            DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale2);
+            DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale3);
+            DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale4);
+        }
+    }
+}
diff --git a/dalvik/src/main/java/dalvik/system/DexFile.java b/dalvik/src/main/java/dalvik/system/DexFile.java
index f1ec29d..0a01a13 100644
--- a/dalvik/src/main/java/dalvik/system/DexFile.java
+++ b/dalvik/src/main/java/dalvik/system/DexFile.java
@@ -41,7 +41,6 @@
     private Object mCookie;
     private Object mInternalCookie;
     private final String mFileName;
-    private final CloseGuard guard = CloseGuard.get();
 
     /**
      * Opens a DEX file from a given File object. This will usually be a ZIP/JAR
@@ -113,7 +112,6 @@
         mCookie = openDexFile(fileName, null, 0, loader, elements);
         mInternalCookie = mCookie;
         mFileName = fileName;
-        guard.open("close");
         //System.out.println("DEX FILE cookie is " + mCookie + " fileName=" + fileName);
     }
 
@@ -250,7 +248,6 @@
             if (closeDexFile(mInternalCookie)) {
                 mInternalCookie = null;
             }
-            guard.close();
             mCookie = null;
         }
     }
@@ -349,9 +346,6 @@
      */
     @Override protected void finalize() throws Throwable {
         try {
-            if (guard != null) {
-                guard.warnIfOpen();
-            }
             if (mInternalCookie != null && !closeDexFile(mInternalCookie)) {
                 throw new AssertionError("Failed to close dex file in finalizer.");
             }
@@ -507,4 +501,12 @@
      */
     public static native String getDexFileStatus(String fileName, String instructionSet)
         throws FileNotFoundException;
+
+    /**
+     * Returns the full file path of the optimized dex file {@code fileName}.  The returned string
+     * is the full file name including path of optimized dex file, if it exists.
+     * @hide
+     */
+    public static native String getDexFileOutputPath(String fileName, String instructionSet)
+        throws FileNotFoundException;
 }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/DataInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/DataInputStreamTest.java
index 67a4e5f..7d89017 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/DataInputStreamTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/DataInputStreamTest.java
@@ -23,6 +23,7 @@
 import java.io.DataOutputStream;
 import java.io.EOFException;
 import java.io.IOException;
+import java.io.InputStream;
 
 public class DataInputStreamTest extends junit.framework.TestCase {
 
@@ -564,6 +565,54 @@
                 + skipped, skipped == fileString.length());
     }
 
+    // b/30268192 : Some apps rely on the exact calls that
+    // DataInputStream makes on the wrapped InputStream. This
+    // test is to prevent *unintentional* regressions but may
+    // change in future releases.
+    public void test_readShortUsesMultiByteRead() throws IOException {
+        ThrowExceptionOnSingleByteReadInputStream
+                is = new ThrowExceptionOnSingleByteReadInputStream();
+        DataInputStream dis = new DataInputStream(is);
+        dis.readShort();
+        is.assertMultiByteReadWasCalled();
+    }
+
+    // b/30268192 : Some apps rely on the exact calls that
+    // DataInputStream makes on the wrapped InputStream. This
+    // test is to prevent *unintentional* regressions but may
+    // change in future releases.
+    public void test_readCharUsesMultiByteRead() throws IOException {
+        ThrowExceptionOnSingleByteReadInputStream
+                is = new ThrowExceptionOnSingleByteReadInputStream();
+        DataInputStream dis = new DataInputStream(is);
+        dis.readChar();
+        is.assertMultiByteReadWasCalled();
+    }
+
+    // b/30268192 : Some apps rely on the exact calls that
+    // DataInputStream makes on the wrapped InputStream. This
+    // test is to prevent *unintentional* regressions but may
+    // change in future releases.
+    public void test_readIntUsesMultiByteRead() throws IOException {
+        ThrowExceptionOnSingleByteReadInputStream
+                is = new ThrowExceptionOnSingleByteReadInputStream();
+        DataInputStream dis = new DataInputStream(is);
+        dis.readInt();
+        is.assertMultiByteReadWasCalled();
+    }
+
+    // b/30268192 : Some apps rely on the exact calls that
+    // DataInputStream makes on the wrapped InputStream. This
+    // test is to prevent *unintentional* regressions but may
+    // change in future releases.
+    public void test_readUnsignedShortUsesMultiByteRead() throws IOException {
+        ThrowExceptionOnSingleByteReadInputStream
+                is = new ThrowExceptionOnSingleByteReadInputStream();
+        DataInputStream dis = new DataInputStream(is);
+        dis.readUnsignedShort();
+        is.assertMultiByteReadWasCalled();
+    }
+
     private void openDataInputStream() throws IOException {
         dis = new DataInputStream(new ByteArrayInputStream(bos.toByteArray()));
     }
@@ -591,4 +640,27 @@
         } catch (Exception e) {
         }
     }
+
+    public static class ThrowExceptionOnSingleByteReadInputStream extends InputStream {
+
+        private boolean multiByteReadWasCalled = false;
+
+        @Override
+        public int read() throws IOException {
+            fail("Should not call single byte read");
+            return 0;
+        }
+
+        @Override
+        public int read(byte[] b, int i, int j) throws IOException {
+            multiByteReadWasCalled = true;
+            return j;
+        }
+
+        public void assertMultiByteReadWasCalled() {
+            if (!multiByteReadWasCalled) {
+                fail("read(byte[], int, int) was not called");
+            }
+        }
+    }
 }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java
index 7ae4617..7fa5fbb 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java
@@ -17,7 +17,6 @@
 
 package org.apache.harmony.tests.java.io;
 
-import junit.framework.TestCase;
 import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInput;
@@ -27,6 +26,7 @@
 import java.io.Serializable;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
+import junit.framework.TestCase;
 
 public class ObjectStreamClassTest extends TestCase {
 
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/VectorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/VectorTest.java
index a9f64a2..a16c4e4 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/VectorTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/VectorTest.java
@@ -30,6 +30,7 @@
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.NoSuchElementException;
 import java.util.Spliterator;
 import java.util.Vector;
@@ -850,6 +851,15 @@
         }
     }
 
+    // http://b/30974375
+    public void test_listIterator_addAndPrevious() {
+        ListIterator<String> it = new Vector<String>().listIterator();
+        assertFalse(it.hasNext());
+        it.add("value");
+        assertEquals("value", it.previous());
+        assertTrue(it.hasNext());
+    }
+
     /**
      * java.util.Vector#remove(int)
      */
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/SocketFactoryTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/SocketFactoryTest.java
index 649be09..52d9142 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/SocketFactoryTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/SocketFactoryTest.java
@@ -126,30 +126,12 @@
     public final void test_createSocket_InetAddressIInetAddressI() throws Exception {
         SocketFactory sf = SocketFactory.getDefault();
         int sport = new ServerSocket(0).getLocalPort();
-        int[] invalidPorts = {Integer.MIN_VALUE, -1, 65536, Integer.MAX_VALUE};
 
         Socket s = sf.createSocket(InetAddress.getLocalHost(), sport,
-                                   InetAddress.getLocalHost(), 0);
+                InetAddress.getLocalHost(), 0);
         assertNotNull(s);
         assertTrue("1: Failed to create socket", s.getPort() == sport);
         int portNumber = s.getLocalPort();
-
-        for (int i = 0; i < invalidPorts.length; i++) {
-            try {
-              sf.createSocket(InetAddress.getLocalHost(), invalidPorts[i],
-                              InetAddress.getLocalHost(), portNumber);
-                fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]);
-            } catch (IllegalArgumentException expected) {
-            }
-
-            try {
-                sf.createSocket(InetAddress.getLocalHost(), sport,
-                                InetAddress.getLocalHost(), invalidPorts[i]);
-                fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]);
-            } catch (IllegalArgumentException expected) {
-            }
-        }
-
         try {
             sf.createSocket(InetAddress.getLocalHost(), sport,
                             InetAddress.getLocalHost(), portNumber);
@@ -165,6 +147,64 @@
         }
     }
 
+    // Checks the behavior of createSocket(InetAddress, int, InetAddress, int) when the
+    // ports are invalid.
+    public void test_createSocket_InetAddressIInetAddressI_IllegalArgumentException()
+            throws Exception {
+        SocketFactory sf = SocketFactory.getDefault();
+        int validPort = new ServerSocket(0).getLocalPort();
+        int[] invalidPorts = {Integer.MIN_VALUE, -1, 65536, Integer.MAX_VALUE};
+
+        for (int i = 0; i < invalidPorts.length; i++) {
+            // Check invalid server port.
+            try (Socket s = sf.createSocket(InetAddress.getLocalHost() /* ServerAddress */,
+                    invalidPorts[i] /* ServerPort */,
+                    InetAddress.getLocalHost() /* ClientAddress */,
+                    validPort /* ClientPort */)) {
+                fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]);
+            } catch (IllegalArgumentException expected) {
+            }
+
+            // Check invalid client port.
+            try (Socket s = sf.createSocket(InetAddress.getLocalHost() /* ServerAddress */,
+                    validPort /* ServerPort */,
+                    InetAddress.getLocalHost() /* ClientAddress */,
+                    invalidPorts[i]) /* ClientPort */){
+                fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]);
+            } catch (IllegalArgumentException expected) {
+            }
+        }
+    }
+
+    // b/31019685
+    // Checks the ordering of port number validation (IllegalArgumentException) and binding error.
+    public void test_createSocket_InetAddressIInetAddressI_ExceptionOrder() throws IOException {
+        int invalidPort = Integer.MAX_VALUE;
+        SocketFactory sf = SocketFactory.getDefault();
+        int validServerPortNumber = new ServerSocket(0).getLocalPort();
+
+        // Create a socket with localhost as the client address so that another attempt to bind
+        // would fail.
+        Socket s = sf.createSocket(InetAddress.getLocalHost() /* ServerAddress */,
+                validServerPortNumber /* ServerPortNumber */,
+                InetAddress.getLocalHost() /* ClientAddress */,
+                0 /* ClientPortNumber */);
+
+        int assignedLocalPortNumber = s.getLocalPort();
+
+        // Create a socket with an invalid port and localhost as the client address. Both
+        // BindException and IllegalArgumentException are expected in this case as the address is
+        // already bound to the socket above and port is invalid, however, to preserve the
+        // precedence order, IllegalArgumentException should be thrown.
+        try (Socket s1 = sf.createSocket(InetAddress.getLocalHost() /* ServerAddress */,
+                invalidPort /* ServerPortNumber */,
+                InetAddress.getLocalHost() /* ClientAddress */,
+                assignedLocalPortNumber /* ClientPortNumber */)) {
+            fail("IllegalArgumentException wasn't thrown for " + invalidPort);
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
     /**
      * javax.net.SocketFactory#createSocket(String host, int port,
      *                                             InetAddress localHost, int localPort)
diff --git a/luni/src/main/java/libcore/icu/TimeZoneNames.java b/luni/src/main/java/libcore/icu/TimeZoneNames.java
index daa915e..917d9ce 100644
--- a/luni/src/main/java/libcore/icu/TimeZoneNames.java
+++ b/luni/src/main/java/libcore/icu/TimeZoneNames.java
@@ -68,7 +68,7 @@
             }
 
             long nativeStart = System.nanoTime();
-            fillZoneStrings(locale.toString(), result);
+            fillZoneStrings(locale.toLanguageTag(), result);
             long nativeEnd = System.nanoTime();
 
             internStrings(result);
diff --git a/luni/src/main/java/libcore/net/MimeUtils.java b/luni/src/main/java/libcore/net/MimeUtils.java
index 3b59b87..88a7392 100644
--- a/luni/src/main/java/libcore/net/MimeUtils.java
+++ b/luni/src/main/java/libcore/net/MimeUtils.java
@@ -210,6 +210,12 @@
         add("application/x-xcf", "xcf");
         add("application/x-xfig", "fig");
         add("application/xhtml+xml", "xhtml");
+        // Video mime types for 3GPP first so they'll be default for guessMimeTypeFromExtension
+        // See RFC 3839 for 3GPP and RFC 4393 for 3GPP2
+        add("video/3gpp", "3gpp");
+        add("video/3gpp", "3gp");
+        add("video/3gpp2", "3gpp2");
+        add("video/3gpp2", "3g2");
         add("audio/3gpp", "3gpp");
         add("audio/aac", "aac");
         add("audio/aac-adts", "aac");
@@ -353,10 +359,6 @@
         add("text/x-tex", "cls");
         add("text/x-vcalendar", "vcs");
         add("text/x-vcard", "vcf");
-        add("video/3gpp", "3gpp");
-        add("video/3gpp", "3gp");
-        add("video/3gpp2", "3gpp2");
-        add("video/3gpp2", "3g2");
         add("video/avi", "avi");
         add("video/dl", "dl");
         add("video/dv", "dif");
diff --git a/luni/src/test/java/com/android/org/bouncycastle/crypto/digests/DigestTest.java b/luni/src/test/java/com/android/org/bouncycastle/crypto/digests/DigestTest.java
index fce8507..ec5ca03 100644
--- a/luni/src/test/java/com/android/org/bouncycastle/crypto/digests/DigestTest.java
+++ b/luni/src/test/java/com/android/org/bouncycastle/crypto/digests/DigestTest.java
@@ -93,9 +93,6 @@
                 + oldTime.toString());
         System.out.println("Time for " + ITERATIONS + " x new hash processing: "
                 + newTime.toString());
-
-        assertTrue("New hash should be faster:\nold=" + oldTime.toString() + "\nnew="
-                + newTime.toString(), newTime.mean() < oldTime.mean());
     }
 
     /**
diff --git a/luni/src/test/java/libcore/java/io/FileInputStreamTest.java b/luni/src/test/java/libcore/java/io/FileInputStreamTest.java
index 74432e5..7ff4684 100644
--- a/luni/src/test/java/libcore/java/io/FileInputStreamTest.java
+++ b/luni/src/test/java/libcore/java/io/FileInputStreamTest.java
@@ -26,7 +26,9 @@
 import java.util.List;
 
 import android.system.ErrnoException;
+import android.system.Os;
 import android.system.OsConstants;
+import android.system.StructStatVfs;
 import junit.framework.TestCase;
 
 import libcore.io.IoUtils;
@@ -226,23 +228,36 @@
     // http://b/28192631
     public void testSkipOnLargeFiles() throws Exception {
         File largeFile = File.createTempFile("FileInputStreamTest_testSkipOnLargeFiles", "");
-        FileOutputStream fos = new FileOutputStream(largeFile);
-        try {
-            byte[] buffer = new byte[1024 * 1024]; // 1 MB
-            for (int i = 0; i < 3 * 1024; i++) { // 3 GB
-                fos.write(buffer);
-            }
-        } finally {
-            fos.close();
+
+        // Required space is 3.1 GB: 3GB for file plus 100M headroom.
+        final long requiredFreeSpaceBytes = 3172L * 1024 * 1024;
+
+        // If system doesn't have enough space free for this test, skip it.
+        final StructStatVfs statVfs = Os.statvfs(largeFile.getPath());
+        final long freeSpaceAvailableBytes = statVfs.f_bsize * statVfs.f_bavail;
+        if (freeSpaceAvailableBytes < requiredFreeSpaceBytes) {
+            return;
         }
 
-        FileInputStream fis = new FileInputStream(largeFile);
-        long lastByte = 3 * 1024 * 1024 * 1024L - 1;
-        assertEquals(0, Libcore.os.lseek(fis.getFD(), 0, OsConstants.SEEK_CUR));
-        assertEquals(lastByte, fis.skip(lastByte));
+        try {
+            FileOutputStream fos = new FileOutputStream(largeFile);
+            try {
+                byte[] buffer = new byte[1024 * 1024]; // 1 MB
+                for (int i = 0; i < 3 * 1024; i++) { // 3 GB
+                    fos.write(buffer);
+                }
+            } finally {
+                fos.close();
+            }
 
-        // Proactively cleanup - it's a pretty large file.
-        assertTrue(largeFile.delete());
+            FileInputStream fis = new FileInputStream(largeFile);
+            long lastByte = 3 * 1024 * 1024 * 1024L - 1;
+            assertEquals(0, Libcore.os.lseek(fis.getFD(), 0, OsConstants.SEEK_CUR));
+            assertEquals(lastByte, fis.skip(lastByte));
+        } finally {
+            // Proactively cleanup - it's a pretty large file.
+            assertTrue(largeFile.delete());
+        }
     }
 
     private static List<Integer> getOpenFdsForPrefix(String path) throws Exception {
diff --git a/luni/src/test/java/libcore/java/lang/OldRuntimeTest.java b/luni/src/test/java/libcore/java/lang/OldRuntimeTest.java
index 294cea2..8397587 100644
--- a/luni/src/test/java/libcore/java/lang/OldRuntimeTest.java
+++ b/luni/src/test/java/libcore/java/lang/OldRuntimeTest.java
@@ -27,6 +27,9 @@
 import java.util.Arrays;
 import java.util.Vector;
 import tests.support.resource.Support_Resources;
+import dalvik.system.VMRuntime;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
 
 public class OldRuntimeTest extends junit.framework.TestCase {
 
@@ -519,4 +522,73 @@
             //expected
         }
     }
+
+    // b/25859957
+    public void test_loadDeprecated() throws Exception {
+        final int savedTargetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
+        try {
+            try {
+                // Call Runtime#load(String, ClassLoader) at API level 24 (N). It will fail
+                // with a UnsatisfiedLinkError because requested library doesn't exits.
+                VMRuntime.getRuntime().setTargetSdkVersion(24);
+                Method loadMethod =
+                        Runtime.class.getDeclaredMethod("load", String.class, ClassLoader.class);
+                loadMethod.setAccessible(true);
+                loadMethod.invoke(Runtime.getRuntime(), "nonExistentLibrary", null);
+                fail();
+            } catch(InvocationTargetException expected) {
+                assertTrue(expected.getCause() instanceof UnsatisfiedLinkError);
+            }
+
+            try {
+                // Call Runtime#load(String, ClassLoader) at API level 25. It will fail
+                // with a IllegalStateException because it's deprecated.
+                VMRuntime.getRuntime().setTargetSdkVersion(25);
+                Method loadMethod =
+                        Runtime.class.getDeclaredMethod("load", String.class, ClassLoader.class);
+                loadMethod.setAccessible(true);
+                loadMethod.invoke(Runtime.getRuntime(), "nonExistentLibrary", null);
+                fail();
+            } catch(InvocationTargetException expected) {
+                assertTrue(expected.getCause() instanceof UnsupportedOperationException);
+            }
+        } finally {
+            VMRuntime.getRuntime().setTargetSdkVersion(savedTargetSdkVersion);
+        }
+    }
+
+    // b/25859957
+    public void test_loadLibraryDeprecated() throws Exception {
+        final int savedTargetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
+        try {
+            try {
+                // Call Runtime#loadLibrary(String, ClassLoader) at API level 24 (N). It will fail
+                // with a UnsatisfiedLinkError because requested library doesn't exits.
+                VMRuntime.getRuntime().setTargetSdkVersion(24);
+                Method loadMethod =
+                        Runtime.class.getDeclaredMethod("loadLibrary", String.class, ClassLoader.class);
+                loadMethod.setAccessible(true);
+                loadMethod.invoke(Runtime.getRuntime(), "nonExistentLibrary", null);
+                fail();
+            } catch(InvocationTargetException expected) {
+                assertTrue(expected.getCause() instanceof UnsatisfiedLinkError);
+            }
+
+            try {
+                // Call Runtime#load(String, ClassLoader) at API level 25. It will fail
+                // with a IllegalStateException because it's deprecated.
+
+                VMRuntime.getRuntime().setTargetSdkVersion(25);
+                Method loadMethod =
+                        Runtime.class.getDeclaredMethod("loadLibrary", String.class, ClassLoader.class);
+                loadMethod.setAccessible(true);
+                loadMethod.invoke(Runtime.getRuntime(), "nonExistentLibrary", null);
+                fail();
+            } catch(InvocationTargetException expected) {
+                assertTrue(expected.getCause() instanceof UnsupportedOperationException);
+            }
+        } finally {
+            VMRuntime.getRuntime().setTargetSdkVersion(savedTargetSdkVersion);
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/java/lang/reflect/Annotations57649Test.java b/luni/src/test/java/libcore/java/lang/reflect/Annotations57649Test.java
index 60e294b..f2f961c 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/Annotations57649Test.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/Annotations57649Test.java
@@ -7,6 +7,12 @@
 public final class Annotations57649Test extends TestCase {
   // https://code.google.com/p/android/issues/detail?id=57649
   public void test57649() throws Exception {
+    // This test consumes a lot of RAM and doesn't release it. Disable on low ram devices.
+    // See b/32004484
+    if (isLowRamDevice()) {
+      return;
+    }
+
     Thread a = runTest(A.class);
     Thread b = runTest(B.class);
     a.join();
@@ -23,6 +29,10 @@
     return t;
   }
 
+  private static boolean isLowRamDevice() {
+    return Boolean.parseBoolean(System.getProperty("android.cts.device.lowram", "false"));
+  }
+
   @Retention(RetentionPolicy.RUNTIME) @interface A0 {}
   @Retention(RetentionPolicy.RUNTIME) @interface A1 {}
   @Retention(RetentionPolicy.RUNTIME) @interface A2 {}
diff --git a/luni/src/test/java/libcore/java/net/DatagramSocketTest.java b/luni/src/test/java/libcore/java/net/DatagramSocketTest.java
index 86e47ec..067291a 100644
--- a/luni/src/test/java/libcore/java/net/DatagramSocketTest.java
+++ b/luni/src/test/java/libcore/java/net/DatagramSocketTest.java
@@ -18,8 +18,11 @@
 
 import junit.framework.TestCase;
 
+import java.lang.reflect.Field;
 import java.net.DatagramSocket;
 import java.net.InetSocketAddress;
+import java.net.DatagramSocketImpl;
+import java.net.InetAddress;
 
 public class DatagramSocketTest extends TestCase {
 
@@ -55,4 +58,21 @@
     assertEquals(-1, ds.getLocalPort());
     assertNull(ds.getLocalSocketAddress());
   }
+  // Socket should become connected even if impl.connect() failed and threw exception.
+  public void test_b31218085() throws Exception {
+    final int port = 9999;
+
+    try (DatagramSocket s = new DatagramSocket()) {
+      // Set fd of DatagramSocket to null, forcing impl.connect() to throw.
+      Field f = DatagramSocket.class.getDeclaredField("impl");
+      f.setAccessible(true);
+      DatagramSocketImpl impl = (DatagramSocketImpl) f.get(s);
+      f = DatagramSocketImpl.class.getDeclaredField("fd");
+      f.setAccessible(true);
+      f.set(impl, null);
+
+      s.connect(InetAddress.getLocalHost(), port);
+      assertTrue(s.isConnected());
+    }
+  }
 }
diff --git a/luni/src/test/java/libcore/java/net/InetAddressTest.java b/luni/src/test/java/libcore/java/net/InetAddressTest.java
index d496801..4f922eb 100644
--- a/luni/src/test/java/libcore/java/net/InetAddressTest.java
+++ b/luni/src/test/java/libcore/java/net/InetAddressTest.java
@@ -20,6 +20,7 @@
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.net.UnknownHostException;
@@ -185,10 +186,8 @@
     public void test_isReachable_neverThrows() throws Exception {
         InetAddress inetAddress = InetAddress.getByName("www.google.com");
 
-        final NetworkInterface netIf;
-        try {
-            netIf = NetworkInterface.getByName("dummy0");
-        } catch (SocketException e) {
+        final NetworkInterface netIf = NetworkInterface.getByName("dummy0");
+        if (netIf == null) {
             System.logI("Skipping test_isReachable_neverThrows because dummy0 isn't available");
             return;
         }
@@ -334,11 +333,15 @@
 
     public void test_getHostNameCaches() throws Exception {
         InetAddress inetAddress = InetAddress.getByAddress(LOOPBACK6_BYTES);
-        // TODO(narayan): Investigate why these tests are suppressed.
-        // assertEquals("::1", inetAddress.getHostString());
+
+        // There should be no cached name.
+        assertEquals("::1", getHostStringWithoutReverseDns(inetAddress));
+
+        // Force the reverse-DNS lookup.
         assertEquals("ip6-localhost", inetAddress.getHostName());
-        // getHostString() should now be different.
-        // assertEquals("ip6-localhost", inetAddress.getHostString());
+
+        // The cached name should now be different.
+        assertEquals("ip6-localhost", getHostStringWithoutReverseDns(inetAddress));
     }
 
     public void test_getByAddress_loopbackIpv4() throws Exception {
@@ -367,7 +370,7 @@
 
     public void test_getByName_empty() throws Exception {
         InetAddress inetAddress = InetAddress.getByName("");
-        assertEquals(LOOPBACK6_BYTES, "localhost", inetAddress);
+        assertEquals(LOOPBACK6_BYTES, "ip6-localhost", inetAddress);
         assertTrue(inetAddress.isLoopbackAddress());
     }
 
@@ -418,6 +421,13 @@
         assertEquals(expectedLoopbackAddresses, createSet(inetAddresses));
     }
 
+    // http://b/29311351
+    public void test_loopbackConstantsPreInitializedNames() {
+        // Note: Inet6Address / Inet4Address equals() does not check host name.
+        assertEquals("ip6-localhost", getHostStringWithoutReverseDns(Inet6Address.LOOPBACK));
+        assertEquals("localhost", getHostStringWithoutReverseDns(Inet4Address.LOOPBACK));
+    }
+
     private static void assertEquals(
         byte[] expectedAddressBytes, String expectedHostname, InetAddress actual) {
         assertArrayEquals(expectedAddressBytes, actual.getAddress());
@@ -433,4 +443,11 @@
     private static Set<InetAddress> createSet(InetAddress... members) {
         return new HashSet<InetAddress>(Arrays.asList(members));
     }
+
+    private static String getHostStringWithoutReverseDns(InetAddress inetAddress) {
+        // The InetAddress API provides no way of avoiding a DNS lookup, but InetSocketAddress
+        // does via InetSocketAddress.getHostString().
+        InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, 9999);
+        return inetSocketAddress.getHostString();
+    }
 }
diff --git a/luni/src/test/java/libcore/java/net/SocketTest.java b/luni/src/test/java/libcore/java/net/SocketTest.java
index 52638d4..e2d3964 100644
--- a/luni/src/test/java/libcore/java/net/SocketTest.java
+++ b/luni/src/test/java/libcore/java/net/SocketTest.java
@@ -21,6 +21,7 @@
 import java.io.OutputStream;
 import java.net.ConnectException;
 import java.net.Inet4Address;
+import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.Proxy;
@@ -34,6 +35,7 @@
 import java.net.UnknownHostException;
 import java.nio.channels.ServerSocketChannel;
 import java.nio.channels.SocketChannel;
+import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
@@ -45,6 +47,10 @@
 
 
 public class SocketTest extends junit.framework.TestCase {
+
+    // This hostname is required to resolve to 127.0.0.1 and ::1 for all tests to pass.
+    private static final String ALL_LOOPBACK_HOSTNAME = "loopback46.unittest.grpc.io";
+
     // See http://b/2980559.
     public void test_close() throws Exception {
         Socket s = new Socket();
@@ -542,4 +548,51 @@
             new SocketThatFailOnClose(InetAddress.getLocalHost(), 1, true);
         } catch(IOException expected) {}
     }
+
+    // b/30007735
+    public void testSocketTestAllAddresses() throws Exception {
+        // Socket Ctor should try all sockets.
+        //
+        // This test creates a server socket bound to 127.0.0.1 or ::1 only, and connects using a
+        // hostname that resolves to both addresses. We should be able to connect to the server
+        // socket in either setup.
+        final String loopbackHost = ALL_LOOPBACK_HOSTNAME;
+
+        assertTrue("Loopback DNS record is unreachable or is invalid.", checkLoopbackHost(
+                loopbackHost));
+
+        final int port = 9999;
+        for (InetAddress addr : new InetAddress[]{ Inet4Address.LOOPBACK, Inet6Address.LOOPBACK }) {
+            try (ServerSocket ss = new ServerSocket(port, 0, addr)) {
+                new Thread(() -> {
+                    try {
+                        ss.accept();
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                }).start();
+
+                assertTrue(canConnect(loopbackHost, port));
+            }
+        }
+    }
+
+    /** Confirm the supplied hostname maps to only loopback addresses. */
+    private static boolean checkLoopbackHost(String host) {
+        try {
+            List<InetAddress> addrs = Arrays.asList(InetAddress.getAllByName(host));
+            return addrs.stream().allMatch(InetAddress::isLoopbackAddress) &&
+                    addrs.contains(Inet4Address.LOOPBACK) && addrs.contains(Inet6Address.LOOPBACK);
+        } catch (UnknownHostException e) {
+            return false;
+        }
+    }
+
+    private static boolean canConnect(String host, int port) {
+        try(Socket sock = new Socket(host, port)) {
+            return sock.isConnected();
+        } catch (IOException e) {
+            return false;
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index fc5283b..9729cf2 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -618,29 +618,59 @@
     }
 
     public void testConnectViaProxyUsingProxyArg() throws Exception {
-        testConnectViaProxy(ProxyConfig.CREATE_ARG);
+        testConnectViaProxy(ProxyConfig.CREATE_ARG, "http://android.com/foo", "android.com");
     }
 
     public void testConnectViaProxyUsingProxySystemProperty() throws Exception {
-        testConnectViaProxy(ProxyConfig.PROXY_SYSTEM_PROPERTY);
+        testConnectViaProxy(
+                ProxyConfig.PROXY_SYSTEM_PROPERTY, "http://android.com/foo", "android.com");
     }
 
     public void testConnectViaProxyUsingHttpProxySystemProperty() throws Exception {
-        testConnectViaProxy(ProxyConfig.HTTP_PROXY_SYSTEM_PROPERTY);
+        testConnectViaProxy(
+                ProxyConfig.HTTP_PROXY_SYSTEM_PROPERTY, "http://android.com/foo", "android.com");
     }
 
-    private void testConnectViaProxy(ProxyConfig proxyConfig) throws Exception {
+    // Regression test for http://b/29983827 : ensure that a trailing "/" is not added to the
+    // HTTP request line when using a proxy.
+    public void testConnectViaProxy_emptyPath() throws Exception {
+        testConnectViaProxy(
+                ProxyConfig.HTTP_PROXY_SYSTEM_PROPERTY, "http://android.com", "android.com");
+    }
+
+    public void testConnectViaProxy_rootPath() throws Exception {
+        testConnectViaProxy(
+                ProxyConfig.HTTP_PROXY_SYSTEM_PROPERTY, "http://android.com/", "android.com");
+    }
+
+    public void testConnectViaProxy_pathWithoutTrailingSlash() throws Exception {
+        testConnectViaProxy(
+                ProxyConfig.HTTP_PROXY_SYSTEM_PROPERTY, "http://android.com/foo", "android.com");
+    }
+
+    public void testConnectViaProxy_pathWithTrailingSlash() throws Exception {
+        testConnectViaProxy(
+                ProxyConfig.HTTP_PROXY_SYSTEM_PROPERTY, "http://android.com/foo/", "android.com");
+    }
+
+    public void testConnectViaProxy_complexUrlWithNoPath() throws Exception {
+        testConnectViaProxy(ProxyConfig.HTTP_PROXY_SYSTEM_PROPERTY,
+                "http://android.com:8080?height=100&width=42", "android.com:8080");
+    }
+
+    private void testConnectViaProxy(ProxyConfig proxyConfig, String urlString, String expectedHost)
+            throws Exception {
         MockResponse mockResponse = new MockResponse().setBody("this response comes via a proxy");
         server.enqueue(mockResponse);
         server.play();
 
-        URL url = new URL("http://android.com/foo");
+        URL url = new URL(urlString);
         HttpURLConnection connection = proxyConfig.connect(server, url);
         assertContent("this response comes via a proxy", connection);
 
         RecordedRequest request = server.takeRequest();
-        assertEquals("GET http://android.com/foo HTTP/1.1", request.getRequestLine());
-        assertContains(request.getHeaders(), "Host: android.com");
+        assertEquals("GET " + urlString + " HTTP/1.1", request.getRequestLine());
+        assertContains(request.getHeaders(), "Host: " + expectedHost);
     }
 
     public void testContentDisagreesWithContentLengthHeader() throws IOException {
@@ -2266,8 +2296,13 @@
         testUrlToRequestMapping("$", "$", "$");
         testUrlToUriMapping("&", "&", "&", "&", "&");
         testUrlToRequestMapping("&", "&", "&");
-        testUrlToUriMapping("'", "'", "'", "%27", "'");
-        testUrlToRequestMapping("'", "'", "%27");
+
+        // http://b/30405333 - upstream OkHttp encodes single quote (') as %27 in query parameters
+        // but this breaks iTunes remote apps: iTunes currently does not accept %27 so we have a
+        // local patch to retain the historic Android behavior of not encoding single quote.
+        testUrlToUriMapping("'", "'", "'", "'", "'");
+        testUrlToRequestMapping("'", "'", "'");
+
         testUrlToUriMapping("(", "(", "(", "(", "(");
         testUrlToRequestMapping("(", "(", "(");
         testUrlToUriMapping(")", ")", ")", ")", ")");
diff --git a/luni/src/test/java/libcore/java/security/PrivilegedActionExceptionTest.java b/luni/src/test/java/libcore/java/security/PrivilegedActionExceptionTest.java
new file mode 100644
index 0000000..0f965e5
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/PrivilegedActionExceptionTest.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.java.security;
+
+import junit.framework.TestCase;
+
+import java.security.PrivilegedActionException;
+
+public class PrivilegedActionExceptionTest extends TestCase {
+
+    /**
+     * PrivilegedActionException's constructor argument may be rethrown by getException() or
+     * getCause().
+     * b/31360928
+     */
+    public void testGetException() {
+        Exception e = new Exception();
+        PrivilegedActionException pae = new PrivilegedActionException(e);
+
+        assertSame(e, pae.getException());
+        assertSame(e, pae.getCause());
+    }
+}
diff --git a/luni/src/test/java/libcore/java/text/DateFormatSymbolsTest.java b/luni/src/test/java/libcore/java/text/DateFormatSymbolsTest.java
index 0c97f34..eb3c8fe 100644
--- a/luni/src/test/java/libcore/java/text/DateFormatSymbolsTest.java
+++ b/luni/src/test/java/libcore/java/text/DateFormatSymbolsTest.java
@@ -161,4 +161,16 @@
             }
         }
     }
+
+    public void test_setZoneStrings_checks_dimensions() throws Exception {
+        DateFormatSymbols dfs = DateFormatSymbols.getInstance();
+        String[][] zoneStrings = dfs.getZoneStrings();
+        zoneStrings[0] = new String[] { "id_only "};
+        try {
+            dfs.setZoneStrings(zoneStrings);
+            fail("No IllegalArgumentException when setting incorrect zoneStrings");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/java/text/DateFormatTest.java b/luni/src/test/java/libcore/java/text/DateFormatTest.java
new file mode 100644
index 0000000..8e215ab
--- /dev/null
+++ b/luni/src/test/java/libcore/java/text/DateFormatTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.java.text;
+
+import junit.framework.TestCase;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+public class DateFormatTest extends TestCase {
+
+    // Regression test for http://b/31762542. If this test fails it implies that changes to
+    // DateFormat.is24Hour will not be effective.
+    public void testIs24Hour_notCached() throws Exception {
+        Boolean originalIs24Hour = DateFormat.is24Hour;
+        try {
+            // These tests hardcode expectations for Locale.US.
+            DateFormat.is24Hour = null; // null == locale default (12 hour for US)
+            checkTimePattern(DateFormat.SHORT, "h:mm a");
+            checkTimePattern(DateFormat.MEDIUM, "h:mm:ss a");
+
+            DateFormat.is24Hour = true; // Explicit 24 hour.
+            checkTimePattern(DateFormat.SHORT, "HH:mm");
+            checkTimePattern(DateFormat.MEDIUM, "HH:mm:ss");
+
+            DateFormat.is24Hour = false; // Explicit 12 hour.
+            checkTimePattern(DateFormat.SHORT, "h:mm a");
+            checkTimePattern(DateFormat.MEDIUM, "h:mm:ss a");
+        } finally {
+            DateFormat.is24Hour = originalIs24Hour;
+        }
+    }
+
+    private static void checkTimePattern(int style, String expectedPattern) {
+        final Locale locale = Locale.US;
+        final Date current = new Date(1468250177000L); // 20160711 15:16:17 GMT
+        DateFormat format = DateFormat.getTimeInstance(style, locale);
+        String actualDateString = format.format(current);
+        SimpleDateFormat sdf = new SimpleDateFormat(expectedPattern, locale);
+        String expectedDateString = sdf.format(current);
+        assertEquals(expectedDateString, actualDateString);
+    }
+}
diff --git a/luni/src/test/java/libcore/java/text/OldBidiTest.java b/luni/src/test/java/libcore/java/text/OldBidiTest.java
index fbf68ea..fe8b6cb 100644
--- a/luni/src/test/java/libcore/java/text/OldBidiTest.java
+++ b/luni/src/test/java/libcore/java/text/OldBidiTest.java
@@ -17,6 +17,7 @@
 
 package libcore.java.text;
 
+import java.text.AttributedCharacterIterator;
 import java.text.Bidi;
 import junit.framework.TestCase;
 
@@ -192,4 +193,16 @@
         }
     }
 
+    // http://b/30652865
+    public void testUnicode9EmojisAreLtrNeutral() {
+        String callMeHand = "\uD83E\uDD19"; // U+1F919 in UTF-16
+        String hebrewAndEmoji = "\u05e9\u05dc" + callMeHand + "\u05d5\u05dd";
+        String latinAndEmoji = "Hel" + callMeHand + "lo";
+        Bidi hebrew = new Bidi(hebrewAndEmoji, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+        assertFalse("Hebrew bidi is mixed: " + hebrew, hebrew.isMixed());
+        assertTrue("Hebrew bidi is not right to left: " + hebrew, hebrew.isRightToLeft());
+        Bidi latin = new Bidi(latinAndEmoji, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+        assertFalse("Latin bidi is mixed: " + latin, latin.isMixed());
+        assertTrue("latin bidi is not left to right: " + latin, latin.isLeftToRight());
+    }
 }
diff --git a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
index fe4e567..43019cc 100644
--- a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
@@ -17,6 +17,7 @@
 package libcore.java.text;
 
 import java.text.DateFormat;
+import java.text.DateFormatSymbols;
 import java.text.ParseException;
 import java.text.ParsePosition;
 import java.text.SimpleDateFormat;
@@ -231,6 +232,9 @@
         if (d == null) {
             fail(pp.toString());
         }
+        if (pp.getIndex() != value.length()) {
+            fail("Value " + value + " must be fully consumed: " +  pp.toString());
+        }
         Calendar c = Calendar.getInstance(tz);
         c.setTime(d);
         return c;
@@ -472,4 +476,51 @@
         df.parse("22 Jul 1977 12:23:45 HST");
         assertEquals(UTC, df.getTimeZone());
     }
+
+    public void testTimeZoneFormattingRespectsSetZoneStrings() throws ParseException {
+        DateFormatSymbols symbols = DateFormatSymbols.getInstance(Locale.ENGLISH);
+        String[][] zoneStrings = symbols.getZoneStrings();
+        TimeZone tz = TimeZone.getTimeZone(zoneStrings[0][0]);
+        String originalTzName = zoneStrings[0][1];
+        symbols.setZoneStrings(zoneStrings);
+        SimpleDateFormat sdf = new SimpleDateFormat("zzzz", symbols);
+        sdf.setTimeZone(tz);
+
+        // just re-setting the default values
+        assertEquals(originalTzName, sdf.format(new Date(1376927400000L)));
+
+        // providing a custom name
+        zoneStrings[0][1] = "CustomTimeZone";
+        symbols.setZoneStrings(zoneStrings);
+        sdf = new SimpleDateFormat("zzzz", symbols);
+        sdf.setTimeZone(tz);
+        assertEquals("CustomTimeZone", sdf.format(new Date(1376927400000L)));
+
+        // setting the name to null should format as GMT[+-]...
+        zoneStrings[0][1] = null;
+        symbols.setZoneStrings(zoneStrings);
+        sdf = new SimpleDateFormat("zzzz", symbols);
+        sdf.setTimeZone(tz);
+        assertTrue(sdf.format(new Date(1376927400000L)).startsWith("GMT"));
+    }
+
+    // http://b/30323478
+    public void testStandaloneWeekdayParsing() throws Exception {
+        Locale fi = new Locale("fi"); // Finnish has separate standalone weekday names
+        // tiistaina = Tuesday (regular)
+        // tiistai = Tuesday (standalone)
+        assertEquals(Calendar.TUESDAY,
+                parseDateUtc(fi, "cccc yyyy", "tiistai 2000").get(Calendar.DAY_OF_WEEK));
+        assertEquals(Calendar.TUESDAY,
+                parseDateUtc(fi, "EEEE yyyy", "tiistaina 2000").get(Calendar.DAY_OF_WEEK));
+        assertCannotParse(fi, "cccc yyyy", "tiistaina 2000");
+        assertCannotParse(fi, "EEEE yyyy", "tiistai 2000");
+    }
+
+    // http://b/30323478
+    public void testStandaloneWeekdayFormatting() throws Exception {
+        Locale fi = new Locale("fi"); // Finnish has separate standalone weekday names
+        assertEquals("torstai", formatDateUtc(fi, "cccc"));
+        assertEquals("torstaina", formatDateUtc(fi, "EEEE"));
+    }
 }
diff --git a/luni/src/test/java/libcore/java/util/TimeZoneTest.java b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
index 5a6fa7f..cb2cd0f 100644
--- a/luni/src/test/java/libcore/java/util/TimeZoneTest.java
+++ b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
@@ -16,13 +16,20 @@
 
 package libcore.java.util;
 
+import junit.framework.TestCase;
+
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Collections;
 import java.util.Date;
+import java.util.List;
 import java.util.Locale;
 import java.util.SimpleTimeZone;
 import java.util.TimeZone;
-import junit.framework.TestCase;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.atomic.AtomicInteger;
 
 public class TimeZoneTest extends TestCase {
     // http://code.google.com/p/android/issues/detail?id=877
@@ -261,6 +268,31 @@
         assertEquals("", failures.toString());
     }
 
+    // http://b/30527513
+    public void testDisplayNamesWithScript() throws Exception {
+        Locale latinLocale = Locale.forLanguageTag("sr-Latn-RS");
+        Locale cyrillicLocale = Locale.forLanguageTag("sr-Cyrl-RS");
+        Locale noScriptLocale = Locale.forLanguageTag("sr-RS");
+        TimeZone tz = TimeZone.getTimeZone("Europe/London");
+
+        final String latinName = "Srednje vreme po Griniču";
+        final String cyrillicName = "Средње време по Гриничу";
+
+        // Check java.util.TimeZone
+        assertEquals(latinName, tz.getDisplayName(latinLocale));
+        assertEquals(cyrillicName, tz.getDisplayName(cyrillicLocale));
+        assertEquals(cyrillicName, tz.getDisplayName(noScriptLocale));
+
+        // Check ICU TimeZoneNames
+        // The one-argument getDisplayName() override uses LONG_GENERIC style which is different
+        // from what java.util.TimeZone uses. Force the LONG style to get equivalent results.
+        final int style = android.icu.util.TimeZone.LONG;
+        android.icu.util.TimeZone utz = android.icu.util.TimeZone.getTimeZone(tz.getID());
+        assertEquals(latinName, utz.getDisplayName(false, style, latinLocale));
+        assertEquals(cyrillicName, utz.getDisplayName(false, style, cyrillicLocale));
+        assertEquals(cyrillicName, utz.getDisplayName(false, style, noScriptLocale));
+    }
+
     // http://b/7955614
     public void testApia() throws Exception {
         TimeZone tz = TimeZone.getTimeZone("Pacific/Apia");
@@ -340,4 +372,107 @@
             TimeZone.setDefault(origTz);
         }
     }
+
+    // http://b/30937209
+    public void testSetDefaultDeadlock() throws InterruptedException, BrokenBarrierException {
+        // Since this tests a deadlock, the test has two fundamental problems:
+        // - it is probabilistic: it's not guaranteed to fail if the problem exists
+        // - if it fails, it will effectively hang the current runtime, as no other thread will
+        //   be able to call TimeZone.getDefault()/setDefault() successfully any more.
+
+        // 10 was too low to be reliable, 100 failed more than half the time (on a bullhead).
+        final int iterations = 100;
+        TimeZone otherTimeZone = TimeZone.getTimeZone("Europe/London");
+        AtomicInteger setterCount = new AtomicInteger();
+        CyclicBarrier startBarrier = new CyclicBarrier(2);
+        Thread setter = new Thread(() -> {
+            waitFor(startBarrier);
+            for (int i = 0; i < iterations; i++) {
+                TimeZone.setDefault(otherTimeZone);
+                TimeZone.setDefault(null);
+                setterCount.set(i+1);
+            }
+        });
+        setter.setName("testSetDefaultDeadlock setter");
+
+        AtomicInteger getterCount = new AtomicInteger();
+        Thread getter = new Thread(() -> {
+            waitFor(startBarrier);
+            for (int i = 0; i < iterations; i++) {
+                android.icu.util.TimeZone.getDefault();
+                getterCount.set(i+1);
+            }
+        });
+        getter.setName("testSetDefaultDeadlock getter");
+
+        setter.start();
+        getter.start();
+
+        // 2 seconds is plenty: If successful, we usually complete much faster.
+        setter.join(1000);
+        getter.join(1000);
+        if (setter.isAlive() || getter.isAlive()) {
+            fail("Threads are still alive. Getter iteration count: " + getterCount.get()
+                    + ", setter iteration count: " + setterCount.get());
+        }
+        // Guard against unexpected uncaught exceptions.
+        assertEquals("Setter iterations", iterations, setterCount.get());
+        assertEquals("Getter iterations", iterations, getterCount.get());
+    }
+
+    // http://b/30979219
+    public void testSetDefaultRace() throws InterruptedException {
+        // Since this tests a race condition, the test is probabilistic: it's not guaranteed to
+        // fail if the problem exists
+
+        // These iterations are significantly faster than the ones in #testSetDefaultDeadlock
+        final int iterations = 10000;
+        List<Throwable> exceptions = Collections.synchronizedList(new ArrayList<>());
+        Thread.UncaughtExceptionHandler handler = (t, e) -> exceptions.add(e);
+
+        CyclicBarrier startBarrier = new CyclicBarrier(2);
+        Thread clearer = new Thread(() -> {
+            waitFor(startBarrier);
+            for (int i = 0; i < iterations; i++) {
+                // This is not public API but can effectively be invoked via
+                // java.util.TimeZone.setDefault. Call it directly to reduce the amount of code
+                // involved in this test.
+                android.icu.util.TimeZone.clearCachedDefault();
+            }
+        });
+        clearer.setName("testSetDefaultRace clearer");
+        clearer.setUncaughtExceptionHandler(handler);
+
+        Thread getter = new Thread(() -> {
+            waitFor(startBarrier);
+            for (int i = 0; i < iterations; i++) {
+                android.icu.util.TimeZone.getDefault();
+            }
+        });
+        getter.setName("testSetDefaultRace getter");
+        getter.setUncaughtExceptionHandler(handler);
+
+        clearer.start();
+        getter.start();
+
+        // 2 seconds is plenty: If successful, we usually complete much faster.
+        clearer.join(1000);
+        getter.join(1000);
+
+        if (!exceptions.isEmpty()) {
+            Throwable firstException = exceptions.get(0);
+            firstException.printStackTrace();
+            fail("Threads did not succeed successfully: " + firstException);
+        }
+        assertFalse("clearer thread is still alive", clearer.isAlive());
+        assertFalse("getter thread is still alive", getter.isAlive());
+    }
+
+    private static void waitFor(CyclicBarrier barrier) {
+        try {
+            barrier.await();
+        } catch (InterruptedException | BrokenBarrierException e) {
+            throw new RuntimeException(e);
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
index 02210ac..2175289 100644
--- a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
@@ -16,7 +16,19 @@
 
 package libcore.java.util.zip;
 
+import android.system.OsConstants;
+import libcore.io.Libcore;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
 import java.util.zip.ZipOutputStream;
 
 public final class ZipFileTest extends AbstractZipFileTest {
@@ -25,4 +37,52 @@
     protected ZipOutputStream createZipOutputStream(OutputStream wrapped) {
         return new ZipOutputStream(wrapped);
     }
+
+    // http://b/30407219
+    public void testZipFileOffsetNeverChangesAfterInit() throws Exception {
+        final File f = createTemporaryZipFile();
+        writeEntries(createZipOutputStream(new BufferedOutputStream(new FileOutputStream(f))),
+                2 /* number of entries */, 1024 /* entry size */, true /* setEntrySize */);
+
+        ZipFile zipFile = new ZipFile(f);
+        FileDescriptor fd = new FileDescriptor();
+        fd.setInt$(zipFile.getFileDescriptor());
+
+        long initialOffset = android.system.Os.lseek(fd, 0, OsConstants.SEEK_CUR);
+
+        Enumeration<? extends ZipEntry> entries = zipFile.entries();
+        assertOffset(initialOffset, fd);
+
+        // Get references to the two elements in the file.
+        ZipEntry entry1 = entries.nextElement();
+        ZipEntry entry2 = entries.nextElement();
+        assertFalse(entries.hasMoreElements());
+        assertOffset(initialOffset, fd);
+
+        InputStream is1 = zipFile.getInputStream(entry1);
+        assertOffset(initialOffset, fd);
+        is1.read(new byte[256]);
+        assertOffset(initialOffset, fd);
+        is1.close();
+
+        assertNotNull(zipFile.getEntry(entry2.getName()));
+        assertOffset(initialOffset, fd);
+
+        zipFile.close();
+    }
+
+    private static void assertOffset(long initialOffset, FileDescriptor fd) throws Exception {
+        long currentOffset = android.system.Os.lseek(fd, 0, OsConstants.SEEK_CUR);
+        assertEquals(initialOffset, currentOffset);
+    }
+
+    // b/31077136
+    public void test_FileNotFound() throws Exception {
+        File nonExistentFile = new File("fileThatDefinitelyDoesntExist.zip");
+        assertFalse(nonExistentFile.exists());
+
+        try (ZipFile zipFile = new ZipFile(nonExistentFile, ZipFile.OPEN_READ)) {
+            fail();
+        } catch(FileNotFoundException expected) {}
+    }
 }
diff --git a/luni/src/test/java/libcore/javax/crypto/MacTest.java b/luni/src/test/java/libcore/javax/crypto/MacTest.java
index 314a564..b308f02 100644
--- a/luni/src/test/java/libcore/javax/crypto/MacTest.java
+++ b/luni/src/test/java/libcore/javax/crypto/MacTest.java
@@ -59,4 +59,14 @@
             Security.removeProvider(mockProvider.getName());
         }
     }
+
+    /**
+     * Aliases used to be wrong due to a typo.
+     * http://b/31114355
+     */
+    public void testMac_correctAlias() throws Exception {
+        Provider androidOpenSSLProvider = Security.getProvider("AndroidOpenSSL");
+        assertEquals("HmacSHA224", androidOpenSSLProvider.get("Alg.Alias.Mac.1.2.840.113549.2.8"));
+        assertEquals("HmacSHA256", androidOpenSSLProvider.get("Alg.Alias.Mac.1.2.840.113549.2.9"));
+    }
 }
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
index d17e32b..5e94b21 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
@@ -80,6 +80,8 @@
 import libcore.tlswire.handshake.CipherSuite;
 import libcore.tlswire.handshake.ClientHello;
 import libcore.tlswire.handshake.CompressionMethod;
+import libcore.tlswire.handshake.EllipticCurve;
+import libcore.tlswire.handshake.EllipticCurvesHelloExtension;
 import libcore.tlswire.handshake.HandshakeMessage;
 import libcore.tlswire.handshake.HelloExtension;
 import libcore.tlswire.handshake.ServerNameHelloExtension;
@@ -1693,6 +1695,31 @@
         }, getSSLSocketFactoriesToTest());
     }
 
+    public void test_SSLSocket_ClientHello_supportedCurves() throws Exception {
+        ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() {
+            @Override
+            public void run(SSLSocketFactory sslSocketFactory) throws Exception {
+                ClientHello clientHello = captureTlsHandshakeClientHello(sslSocketFactory);
+
+                EllipticCurvesHelloExtension ecExtension = (EllipticCurvesHelloExtension)
+                        clientHello.findExtensionByType(HelloExtension.TYPE_ELLIPTIC_CURVES);
+                final String[] supportedCurves;
+                if (ecExtension == null) {
+                    supportedCurves = new String[0];
+                } else {
+                    assertTrue(ecExtension.wellFormed);
+                    supportedCurves = new String[ecExtension.supported.size()];
+                    for (int i = 0; i < ecExtension.supported.size(); i++) {
+                        EllipticCurve curve = ecExtension.supported.get(i);
+                        supportedCurves[i] = curve.toString();
+                    }
+                }
+
+                StandardNames.assertDefaultEllipticCurves(supportedCurves);
+            }
+        }, getSSLSocketFactoriesToTest());
+    }
+
     public void test_SSLSocket_ClientHello_clientProtocolVersion() throws Exception {
         ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() {
             @Override
diff --git a/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java b/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java
index 4f5d658..5471b1f 100644
--- a/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java
+++ b/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java
@@ -120,6 +120,30 @@
         expectExceptionInDNConstructor("l=\\g0");
     }
 
+    public void testNegativeLen() {
+        try {
+            X500Principal p = new X500Principal(new byte[]{
+                    0x30, // DerValue.tag_Sequence read in DerValue#getSequence
+                    9,    // Length of the vector. read in readVector.
+                          // DerInputStream.getLength will just return this as 10 & 0x80 == 0
+                    -1,   // Tag of the first value in the sequencevalue. Convenient so that it
+                          // doesn't hold DerIndefLenConverter.isEOC()
+                    (byte) 0x80, // Encoding in indefinite form
+                    -1,          // Second tag to be read by DerIndefLenConverter
+                    (byte) 0x84, // Second length byte to be read, 0x80 means long form, 4 bytes
+                    (byte) 0xff, // Length to be read by DerIndefLenConverter, -6, will move the
+                                 // buffer position to the second tag
+                    (byte) 0xff,
+                    (byte) 0xff,
+                    (byte) -6,
+                    0,           // Needed as otherwise it's detected that there's nothing after
+                    // the length
+            });
+            fail("expected IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
     private void expectExceptionInDNConstructor(String dn) {
         try {
             X500Principal principal = new X500Principal(dn);
diff --git a/luni/src/test/java/libcore/net/MimeUtilsTest.java b/luni/src/test/java/libcore/net/MimeUtilsTest.java
index ff22632..8b34ea2 100644
--- a/luni/src/test/java/libcore/net/MimeUtilsTest.java
+++ b/luni/src/test/java/libcore/net/MimeUtilsTest.java
@@ -18,8 +18,6 @@
 
 import junit.framework.TestCase;
 
-import libcore.net.MimeUtils;
-
 public class MimeUtilsTest extends TestCase {
   public void test_15715370() {
     assertEquals("audio/flac", MimeUtils.guessMimeTypeFromExtension("flac"));
@@ -52,4 +50,11 @@
   public void test_18390752() {
     assertEquals("jpg", MimeUtils.guessExtensionFromMimeType("image/jpeg"));
   }
+
+  public void test_30793548() {
+    assertEquals("video/3gpp", MimeUtils.guessMimeTypeFromExtension("3gpp"));
+    assertEquals("video/3gpp", MimeUtils.guessMimeTypeFromExtension("3gp"));
+    assertEquals("video/3gpp2", MimeUtils.guessMimeTypeFromExtension("3gpp2"));
+    assertEquals("video/3gpp2", MimeUtils.guessMimeTypeFromExtension("3g2"));
+  }
 }
diff --git a/luni/src/test/resources/tests/api/java/io/sameFieldNames.dex b/luni/src/test/resources/tests/api/java/io/sameFieldNames.dex
new file mode 100644
index 0000000..ada4935
--- /dev/null
+++ b/luni/src/test/resources/tests/api/java/io/sameFieldNames.dex
Binary files differ
diff --git a/luni/src/test/resources/tests/api/java/io/sameFieldNames.smali b/luni/src/test/resources/tests/api/java/io/sameFieldNames.smali
new file mode 100644
index 0000000..657b965
--- /dev/null
+++ b/luni/src/test/resources/tests/api/java/io/sameFieldNames.smali
@@ -0,0 +1,17 @@
+# Source for sameFieldNames.dex
+.class public LsameFieldNames;
+.super Ljava/lang/Object;
+.implements Ljava/io/Serializable;
+
+# Test multiple fields with the same name and different types.
+# (Invalid in Java language but valid in bytecode.)
+.field public a:J
+.field public a:I
+.field public a:Ljava/lang/Integer;
+.field public a:Ljava/lang/Long;
+
+.method public constructor <init>()V
+    .registers 2
+    invoke-direct {p0}, Ljava/lang/Object;-><init>()V
+    return-void
+.end method
diff --git a/ojluni/src/main/java/com/sun/net/ssl/internal/ssl/Provider.java b/ojluni/src/main/java/com/sun/net/ssl/internal/ssl/Provider.java
deleted file mode 100755
index b1a08ce..0000000
--- a/ojluni/src/main/java/com/sun/net/ssl/internal/ssl/Provider.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.net.ssl.internal.ssl;
-
-import sun.security.ssl.SunJSSE;
-
-/**
- * Main class for the SunJSSE provider. The actual code was moved to the
- * class sun.security.ssl.SunJSSE, but for backward compatibility we
- * continue to use this class as the main Provider class.
- */
-public final class Provider extends SunJSSE {
-
-    private static final long serialVersionUID = 3231825739635378733L;
-
-    // standard constructor
-    public Provider() {
-        super();
-    }
-
-    // prefered constructor to enable FIPS mode at runtime
-    public Provider(java.security.Provider cryptoProvider) {
-        super(cryptoProvider);
-    }
-
-    // constructor to enable FIPS mode from java.security file
-    public Provider(String cryptoProvider) {
-        super(cryptoProvider);
-    }
-
-    // public for now, but we may want to change it or not document it.
-    public static synchronized boolean isFIPS() {
-        return SunJSSE.isFIPS();
-    }
-
-    /**
-     * Installs the JSSE provider.
-     */
-    public static synchronized void install() {
-        /* nop. Remove this method in the future. */
-    }
-
-}
diff --git a/ojluni/src/main/java/java/io/DataInputStream.java b/ojluni/src/main/java/java/io/DataInputStream.java
index 7b24b74..19d4067 100755
--- a/ojluni/src/main/java/java/io/DataInputStream.java
+++ b/ojluni/src/main/java/java/io/DataInputStream.java
@@ -25,6 +25,9 @@
 
 package java.io;
 
+import java.nio.ByteOrder;
+import libcore.io.Memory;
+
 /**
  * A data input stream lets an application read primitive Java data
  * types from an underlying input stream in a machine-independent
@@ -309,11 +312,10 @@
      * @see        java.io.FilterInputStream#in
      */
     public final short readShort() throws IOException {
-        int ch1 = in.read();
-        int ch2 = in.read();
-        if ((ch1 | ch2) < 0)
-            throw new EOFException();
-        return (short)((ch1 << 8) + (ch2 << 0));
+        // b/30268192
+        // Android-changed: Use read(byte[], int, int) instead of read().
+        readFully(readBuffer, 0, 2);
+        return Memory.peekShort(readBuffer, 0, ByteOrder.BIG_ENDIAN);
     }
 
     /**
@@ -334,11 +336,10 @@
      * @see        java.io.FilterInputStream#in
      */
     public final int readUnsignedShort() throws IOException {
-        int ch1 = in.read();
-        int ch2 = in.read();
-        if ((ch1 | ch2) < 0)
-            throw new EOFException();
-        return (ch1 << 8) + (ch2 << 0);
+        // b/30268192
+        // Android-changed: Use read(byte[], int, int) instead of read().
+        readFully(readBuffer, 0, 2);
+        return Memory.peekShort(readBuffer, 0, ByteOrder.BIG_ENDIAN) & 0xffff;
     }
 
     /**
@@ -359,11 +360,10 @@
      * @see        java.io.FilterInputStream#in
      */
     public final char readChar() throws IOException {
-        int ch1 = in.read();
-        int ch2 = in.read();
-        if ((ch1 | ch2) < 0)
-            throw new EOFException();
-        return (char)((ch1 << 8) + (ch2 << 0));
+        // b/30268192
+        // Android-changed: Use read(byte[], int, int) instead of read().
+        readFully(readBuffer, 0, 2);
+        return (char)Memory.peekShort(readBuffer, 0, ByteOrder.BIG_ENDIAN);
     }
 
     /**
@@ -384,13 +384,10 @@
      * @see        java.io.FilterInputStream#in
      */
     public final int readInt() throws IOException {
-        int ch1 = in.read();
-        int ch2 = in.read();
-        int ch3 = in.read();
-        int ch4 = in.read();
-        if ((ch1 | ch2 | ch3 | ch4) < 0)
-            throw new EOFException();
-        return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
+        // b/30268192
+        // Android-changed: Use read(byte[], int, int) instead of read().
+        readFully(readBuffer, 0, 4);
+        return Memory.peekInt(readBuffer, 0, ByteOrder.BIG_ENDIAN);
     }
 
     private byte readBuffer[] = new byte[8];
diff --git a/ojluni/src/main/java/java/io/ObjectStreamClass.java b/ojluni/src/main/java/java/io/ObjectStreamClass.java
index a157f4d..ffbde98 100755
--- a/ojluni/src/main/java/java/io/ObjectStreamClass.java
+++ b/ojluni/src/main/java/java/io/ObjectStreamClass.java
@@ -2246,13 +2246,9 @@
             ObjectStreamField f = fields[i], m = null;
             for (int j = 0; j < localFields.length; j++) {
                 ObjectStreamField lf = localFields[j];
-                if (f.getName().equals(lf.getName())) {
-                    if ((f.isPrimitive() || lf.isPrimitive()) &&
-                        f.getTypeCode() != lf.getTypeCode())
-                    {
-                        throw new InvalidClassException(localDesc.name,
-                            "incompatible types for field " + f.getName());
-                    }
+                // Android-changed: We can have fields with a same name and a different type.
+                if (f.getName().equals(lf.getName()) &&
+                    f.getSignature().equals(lf.getSignature())) {
                     if (lf.getField() != null) {
                         m = new ObjectStreamField(
                             lf.getField(), lf.isUnshared(), false);
diff --git a/ojluni/src/main/java/java/lang/Character.java b/ojluni/src/main/java/java/lang/Character.java
index 5b9038a..267d1a7 100755
--- a/ojluni/src/main/java/java/lang/Character.java
+++ b/ojluni/src/main/java/java/lang/Character.java
@@ -6227,6 +6227,15 @@
      * @since   1.5
      */
     public static int toLowerCase(int codePoint) {
+        if (codePoint >= 'A' && codePoint <= 'Z') {
+            return codePoint + ('a' - 'A');
+        }
+
+        // All ASCII codepoints except the ones above remain unchanged.
+        if (codePoint < 0x80) {
+            return codePoint;
+        }
+
         return toLowerCaseImpl(codePoint);
     }
 
@@ -6289,6 +6298,15 @@
      * @since   1.5
      */
     public static int toUpperCase(int codePoint) {
+        if (codePoint >= 'a' && codePoint <= 'z') {
+            return codePoint - ('a' - 'A');
+        }
+
+        // All ASCII codepoints except the ones above remain unchanged.
+        if (codePoint < 0x80) {
+            return codePoint;
+        }
+
         return toUpperCaseImpl(codePoint);
     }
 
diff --git a/ojluni/src/main/java/java/lang/Runtime.java b/ojluni/src/main/java/java/lang/Runtime.java
index 61c2502..5e63dd8 100755
--- a/ojluni/src/main/java/java/lang/Runtime.java
+++ b/ojluni/src/main/java/java/lang/Runtime.java
@@ -868,11 +868,22 @@
      */
     @CallerSensitive
     public void load(String filename) {
-        load0(VMStack.getStackClass2(), filename);
+        load0(VMStack.getStackClass1(), filename);
+    }
+
+    /** Check target sdk, if it's higher than N, we throw an UnsupportedOperationException */
+    private void checkTargetSdkVersionForLoad(String methodName) {
+        final int targetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
+        if (targetSdkVersion > 24) {
+            throw new UnsupportedOperationException(methodName + " is not supported on SDK " +
+                                                    targetSdkVersion);
+        }
     }
 
     // Fixes b/25859957 regression. Depending on private methods is bad, mkay.
     void load(String absolutePath, ClassLoader loader) {
+        checkTargetSdkVersionForLoad("java.lang.Runtime#load(String, ClassLoader)");
+
         java.lang.System.logE("java.lang.Runtime#load(String, ClassLoader)" +
                               " is private and will be removed in a future Android release");
         if (absolutePath == null) {
@@ -951,6 +962,7 @@
      * @hide
      */
     public void loadLibrary(String libname, ClassLoader classLoader) {
+        checkTargetSdkVersionForLoad("java.lang.Runtime#loadLibrary(String, ClassLoader)");
         java.lang.System.logE("java.lang.Runtime#loadLibrary(String, ClassLoader)" +
                               " is private and will be removed in a future Android release");
         loadLibrary0(classLoader, libname);
diff --git a/ojluni/src/main/java/java/net/DatagramSocket.java b/ojluni/src/main/java/java/net/DatagramSocket.java
index 966f30f..13b54b0 100755
--- a/ojluni/src/main/java/java/net/DatagramSocket.java
+++ b/ojluni/src/main/java/java/net/DatagramSocket.java
@@ -142,37 +142,34 @@
         if (!isBound())
           bind(new InetSocketAddress(0));
 
-        // ----- BEGIN android -----
-        connectedAddress = address;
-        connectedPort = port;
-        // ----- END android -----
-
-        // old impls do not support connect/disconnect
-        if (oldImpl || (impl instanceof AbstractPlainDatagramSocketImpl &&
-             ((AbstractPlainDatagramSocketImpl)impl).nativeConnectDisabled())) {
-            connectState = ST_CONNECTED_NO_IMPL;
-        } else {
-          /* ----- BEGIN android -----
-          try {
-              getImpl().connect(address, port);
-
-              // socket is now connected by the impl
-              connectState = ST_CONNECTED;
-          } catch (SocketException se) {
-                // connection will be emulated by DatagramSocket
+        // Android-changed: This section now throws any SocketException generated by connect()
+        // to enable it to be recorded as the pendingConnectException. It has been enclosed in a
+        // try-finally to ensure connectedAddress and connectedPort are set when the exception
+        // is thrown.
+        try {
+            // old impls do not support connect/disconnect
+            // Android-changed: Added special handling for AbstractPlainDatagramSocketImpl in
+            // the condition below.
+            if (oldImpl || (impl instanceof AbstractPlainDatagramSocketImpl &&
+                    ((AbstractPlainDatagramSocketImpl)impl).nativeConnectDisabled())) {
                 connectState = ST_CONNECTED_NO_IMPL;
-          }*/
-          getImpl().connect(address, port);
+            } else {
+                try {
+                    getImpl().connect(address, port);
 
-          // socket is now connected by the impl
-          connectState = ST_CONNECTED;
-          // ----- END android -----
+                    // socket is now connected by the impl
+                    connectState = ST_CONNECTED;
+                } catch (SocketException se) {
+                    // connection will be emulated by DatagramSocket
+                    connectState = ST_CONNECTED_NO_IMPL;
+                    // Android-changed: Propagate the SocketException so connect() can store it.
+                    throw se;
+                }
+           }
+        } finally {
+            connectedAddress = address;
+            connectedPort = port;
         }
-
-        /* ----- BEGIN android -----
-        connectedAddress = address;
-        connectedPort = port;
-        ----- END android ----- */
     }
 
 
diff --git a/ojluni/src/main/java/java/net/Inet6Address.java b/ojluni/src/main/java/java/net/Inet6Address.java
index 4b353e5..d55fab9 100755
--- a/ojluni/src/main/java/java/net/Inet6Address.java
+++ b/ojluni/src/main/java/java/net/Inet6Address.java
@@ -174,7 +174,7 @@
             new Inet6Address("::", new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0);
 
     /** @hide */
-    public static final InetAddress LOOPBACK = new Inet6Address("localhost",
+    public static final InetAddress LOOPBACK = new Inet6Address("ip6-localhost",
             new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, 0);
 
     /**
diff --git a/ojluni/src/main/java/java/net/Socket.java b/ojluni/src/main/java/java/net/Socket.java
index 2aa057f..96a7355 100755
--- a/ojluni/src/main/java/java/net/Socket.java
+++ b/ojluni/src/main/java/java/net/Socket.java
@@ -207,9 +207,7 @@
     public Socket(String host, int port)
         throws UnknownHostException, IOException
     {
-        this(host != null ? new InetSocketAddress(host, port) :
-             new InetSocketAddress(InetAddress.getByName(null), port),
-             (SocketAddress) null, true);
+        this(InetAddress.getAllByName(host), port, (SocketAddress) null, true);
     }
 
     /**
@@ -240,8 +238,7 @@
      * @see        SecurityManager#checkConnect
      */
     public Socket(InetAddress address, int port) throws IOException {
-        this(address != null ? new InetSocketAddress(address, port) : null,
-             (SocketAddress) null, true);
+        this(nonNullAddress(address), port, (SocketAddress) null, true);
     }
 
     /**
@@ -279,8 +276,7 @@
      */
     public Socket(String host, int port, InetAddress localAddr,
                   int localPort) throws IOException {
-        this(host != null ? new InetSocketAddress(host, port) :
-               new InetSocketAddress(InetAddress.getByName(null), port),
+        this(InetAddress.getAllByName(host), port,
              new InetSocketAddress(localAddr, localPort), true);
     }
 
@@ -318,7 +314,7 @@
      */
     public Socket(InetAddress address, int port, InetAddress localAddr,
                   int localPort) throws IOException {
-        this(address != null ? new InetSocketAddress(address, port) : null,
+        this(nonNullAddress(address), port,
              new InetSocketAddress(localAddr, localPort), true);
     }
 
@@ -364,9 +360,7 @@
      */
     @Deprecated
     public Socket(String host, int port, boolean stream) throws IOException {
-        this(host != null ? new InetSocketAddress(host, port) :
-               new InetSocketAddress(InetAddress.getByName(null), port),
-             (SocketAddress) null, stream);
+        this(InetAddress.getAllByName(host), port, (SocketAddress) null, stream);
     }
 
     /**
@@ -407,32 +401,57 @@
      */
     @Deprecated
     public Socket(InetAddress host, int port, boolean stream) throws IOException {
-        this(host != null ? new InetSocketAddress(host, port) : null,
-             new InetSocketAddress(0), stream);
+        this(nonNullAddress(host), port, new InetSocketAddress(0), stream);
     }
 
-    private Socket(SocketAddress address, SocketAddress localAddr,
-                   boolean stream) throws IOException {
-        setImpl();
-
+    private static InetAddress[] nonNullAddress(InetAddress address) {
         // backward compatibility
         if (address == null)
             throw new NullPointerException();
 
-        try {
-            createImpl(stream);
-            if (localAddr != null)
-                bind(localAddr);
-            if (address != null)
+        return new InetAddress[] { address };
+    }
+
+    // Android-changed: Socket ctor should try all addresses
+    // b/30007735
+    private Socket(InetAddress[] addresses, int port, SocketAddress localAddr,
+            boolean stream) throws IOException {
+        if (addresses == null || addresses.length == 0) {
+            throw new SocketException("Impossible: empty address list");
+        }
+
+        for (int i = 0; i < addresses.length; i++) {
+            setImpl();
+            try {
+                InetSocketAddress address = new InetSocketAddress(addresses[i], port);
+                createImpl(stream);
+                if (localAddr != null) {
+                    bind(localAddr);
+                }
                 connect(address);
-        } catch (IOException e) {
-            // Do not call #close, classes that extend this class may do not expect a call
-            // to #close coming from the superclass constructor.
-            if (impl != null) {
-                impl.close();
+                break;
+            } catch (IOException | IllegalArgumentException | SecurityException e) {
+                try {
+                    // Android-changed:
+                    // Do not call #close, classes that extend this class may do not expect a call
+                    // to #close coming from the superclass constructor.
+                    impl.close();
+                    closed = true;
+                } catch (IOException ce) {
+                    e.addSuppressed(ce);
+                }
+
+                // Only stop on the last address.
+                if (i == addresses.length - 1) {
+                    throw e;
+                }
             }
-            closed = true;
-            throw e;
+
+            // Discard the connection state and try again.
+            impl = null;
+            created = false;
+            bound = false;
+            closed = false;
         }
     }
 
diff --git a/ojluni/src/main/java/java/nio/charset/Charset.java b/ojluni/src/main/java/java/nio/charset/Charset.java
index f85b82b..17e1160 100755
--- a/ojluni/src/main/java/java/nio/charset/Charset.java
+++ b/ojluni/src/main/java/java/nio/charset/Charset.java
@@ -214,10 +214,7 @@
  * input sequence are not omitted since the same code is used to represent
  * <small>ZERO-WIDTH NON-BREAKING SPACE</small>.
  *
- * <p> Every instance of the Java virtual machine has a default charset, which
- * may or may not be one of the standard charsets.  The default charset is
- * determined during virtual-machine startup and typically depends upon the
- * locale and charset being used by the underlying operating system. </p>
+ * <p>Android note: The Android platform default is always UTF-8.
  *
  * <p>The {@link StandardCharsets} class defines constants for each of the
  * standard charsets.
@@ -653,9 +650,7 @@
     /**
      * Returns the default charset of this Java virtual machine.
      *
-     * <p> The default charset is determined during virtual-machine startup and
-     * typically depends upon the locale and charset of the underlying
-     * operating system.
+     * <p>Android note: The Android platform default is always UTF-8.
      *
      * @return  A charset object for the default charset
      *
diff --git a/ojluni/src/main/java/java/security/PrivilegedActionException.java b/ojluni/src/main/java/java/security/PrivilegedActionException.java
index af89fb5..83d855a 100755
--- a/ojluni/src/main/java/java/security/PrivilegedActionException.java
+++ b/ojluni/src/main/java/java/security/PrivilegedActionException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,11 +27,81 @@
 
 /**
  * Legacy security code; do not use.
+ *
+ * This exception is thrown by
+ * {@code doPrivileged(PrivilegedExceptionAction)} and
+ * {@code doPrivileged(PrivilegedExceptionAction,
+ * AccessControlContext context)} to indicate
+ * that the action being performed threw a checked exception.  The exception
+ * thrown by the action can be obtained by calling the
+ * {@code getException} method.  In effect, an
+ * {@code PrivilegedActionException} is a "wrapper"
+ * for an exception thrown by a privileged action.
+ *
+ * <p>As of release 1.4, this exception has been retrofitted to conform to
+ * the general purpose exception-chaining mechanism.  The "exception thrown
+ * by the privileged computation" that is provided at construction time and
+ * accessed via the {@link #getException()} method is now known as the
+ * <i>cause</i>, and may be accessed via the {@link Throwable#getCause()}
+ * method, as well as the aforementioned "legacy method."
+ *
+ * @see PrivilegedExceptionAction
+ * @see AccessController#doPrivileged(PrivilegedExceptionAction)
+ * @see AccessController#doPrivileged(PrivilegedExceptionAction,AccessControlContext)
  */
-
 public class PrivilegedActionException extends Exception {
+    // use serialVersionUID from JDK 1.2.2 for interoperability
+    private static final long serialVersionUID = 4724086851538908602L;
 
-    public PrivilegedActionException(Exception exception) { super(exception); }
+    /**
+     * @serial
+     */
+    private Exception exception;
 
-    public Exception getException() { return null; }
+    /**
+     * Constructs a new PrivilegedActionException &quot;wrapping&quot;
+     * the specific Exception.
+     *
+     * @param exception The exception thrown
+     */
+    public PrivilegedActionException(Exception exception) {
+        super((Throwable)null);  // Disallow initCause
+        this.exception = exception;
+    }
+
+    /**
+     * Returns the exception thrown by the privileged computation that
+     * resulted in this {@code PrivilegedActionException}.
+     *
+     * <p>This method predates the general-purpose exception chaining facility.
+     * The {@link Throwable#getCause()} method is now the preferred means of
+     * obtaining this information.
+     *
+     * @return the exception thrown by the privileged computation that
+     *         resulted in this {@code PrivilegedActionException}.
+     * @see PrivilegedExceptionAction
+     * @see AccessController#doPrivileged(PrivilegedExceptionAction)
+     * @see AccessController#doPrivileged(PrivilegedExceptionAction,
+     *                                            AccessControlContext)
+     */
+    public Exception getException() {
+        return exception;
+    }
+
+    /**
+     * Returns the cause of this exception (the exception thrown by
+     * the privileged computation that resulted in this
+     * {@code PrivilegedActionException}).
+     *
+     * @return  the cause of this exception.
+     * @since   1.4
+     */
+    public Throwable getCause() {
+        return exception;
+    }
+
+    public String toString() {
+        String s = getClass().getName();
+        return (exception != null) ? (s + ": " + exception.toString()) : s;
+    }
 }
diff --git a/ojluni/src/main/java/java/text/SimpleDateFormat.java b/ojluni/src/main/java/java/text/SimpleDateFormat.java
index b435583..62cbd00 100755
--- a/ojluni/src/main/java/java/text/SimpleDateFormat.java
+++ b/ojluni/src/main/java/java/text/SimpleDateFormat.java
@@ -52,6 +52,8 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import libcore.icu.LocaleData;
+import libcore.icu.TimeZoneNames;
+
 import sun.util.calendar.CalendarUtils;
 
 import static java.text.DateFormatSymbols.*;
@@ -500,12 +502,6 @@
     private static final String GMT = "GMT";
 
     /**
-     * Cache to hold the DateTimePatterns of a Locale.
-     */
-    private static final ConcurrentMap<Locale, String[]> cachedLocaleData
-        = new ConcurrentHashMap<Locale, String[]>(3);
-
-    /**
      * Cache NumberFormat instances with Locale key.
      */
     private static final ConcurrentMap<Locale, NumberFormat> cachedNumberFormatData
@@ -616,33 +612,20 @@
         // initialize calendar and related fields
         initializeCalendar(loc);
 
-        /* try the cache first */
-        String[] dateTimePatterns = cachedLocaleData.get(loc);
-        if (dateTimePatterns == null) { /* cache miss */
-            LocaleData localeData = LocaleData.get(loc);
-            dateTimePatterns = new String[9];
-            dateTimePatterns[DateFormat.SHORT + 4] = localeData.getDateFormat(DateFormat.SHORT);
-            dateTimePatterns[DateFormat.MEDIUM + 4] = localeData.getDateFormat(DateFormat.MEDIUM);
-            dateTimePatterns[DateFormat.LONG + 4] = localeData.getDateFormat(DateFormat.LONG);
-            dateTimePatterns[DateFormat.FULL + 4] = localeData.getDateFormat(DateFormat.FULL);
-            dateTimePatterns[DateFormat.SHORT] = localeData.getTimeFormat(DateFormat.SHORT);
-            dateTimePatterns[DateFormat.MEDIUM] = localeData.getTimeFormat(DateFormat.MEDIUM);
-            dateTimePatterns[DateFormat.LONG] = localeData.getTimeFormat(DateFormat.LONG);
-            dateTimePatterns[DateFormat.FULL] = localeData.getTimeFormat(DateFormat.FULL);
-            dateTimePatterns[8] = "{0} {1}";
-            /* update cache */
-            cachedLocaleData.putIfAbsent(loc, dateTimePatterns);
-        }
         formatData = DateFormatSymbols.getInstanceRef(loc);
+        LocaleData localeData = LocaleData.get(loc);
         if ((timeStyle >= 0) && (dateStyle >= 0)) {
-            Object[] dateTimeArgs = {dateTimePatterns[dateStyle + 4], dateTimePatterns[timeStyle]};
-            pattern = MessageFormat.format(dateTimePatterns[8], dateTimeArgs);
+            Object[] dateTimeArgs = {
+                localeData.getDateFormat(dateStyle),
+                localeData.getTimeFormat(timeStyle),
+            };
+            pattern = MessageFormat.format("{0} {1}", dateTimeArgs);
         }
         else if (timeStyle >= 0) {
-            pattern = dateTimePatterns[timeStyle];
+            pattern = localeData.getTimeFormat(timeStyle);
         }
         else if (dateStyle >= 0) {
-            pattern = dateTimePatterns[dateStyle + 4];
+            pattern = localeData.getDateFormat(dateStyle);
         }
         else {
             throw new IllegalArgumentException("No date or time style specified");
@@ -1193,7 +1176,13 @@
                 TimeZone tz = calendar.getTimeZone();
                 boolean daylight = (calendar.get(Calendar.DST_OFFSET) != 0);
                 int tzstyle = count < 4 ? TimeZone.SHORT : TimeZone.LONG;
-                String zoneString = tz.getDisplayName(daylight, tzstyle, formatData.locale);
+                String zoneString;
+                if (formatData.isZoneStringsSet) {
+                    zoneString = TimeZoneNames.getDisplayName(
+                            formatData.getZoneStringsWrapper(), tz.getID(), daylight, tzstyle);
+                } else {
+                    zoneString = tz.getDisplayName(daylight, tzstyle, formatData.locale);
+                }
                 if (zoneString != null) {
                     buffer.append(zoneString);
                 } else {
@@ -1966,7 +1955,7 @@
             case PATTERN_STANDALONE_DAY_OF_WEEK: // 'c'
             {
                 final int idx = parseWeekday(text, start, field, useDateFormatSymbols,
-                        false /* standalone */, calb);
+                        true /* standalone */, calb);
                 if (idx > 0) {
                     return idx;
                 }
diff --git a/ojluni/src/main/java/java/util/Vector.java b/ojluni/src/main/java/java/util/Vector.java
index b2bc200..0f2dedd 100755
--- a/ojluni/src/main/java/java/util/Vector.java
+++ b/ojluni/src/main/java/java/util/Vector.java
@@ -1238,6 +1238,7 @@
                 checkForComodification();
                 Vector.this.add(i, e);
                 expectedModCount = modCount;
+                limit++;
             }
             cursor = i + 1;
             lastRet = -1;
diff --git a/ojluni/src/main/java/java/util/zip/ZipFile.java b/ojluni/src/main/java/java/util/zip/ZipFile.java
index e6624af..6a5a366 100755
--- a/ojluni/src/main/java/java/util/zip/ZipFile.java
+++ b/ojluni/src/main/java/java/util/zip/ZipFile.java
@@ -31,6 +31,7 @@
 import java.io.IOException;
 import java.io.EOFException;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayDeque;
@@ -203,9 +204,15 @@
                                                Integer.toHexString(mode));
         }
 
-        // Android-changed: Error out early if the file is too short.
-        if (file.length() < ZipConstants.ENDHDR) {
-            throw new ZipException("File too short to be a zip file: " + file.length());
+
+        // Android-changed: Error out early if the file is too short or non-existent.
+        long length = file.length();
+        if (length < ZipConstants.ENDHDR) {
+            if (length == 0 && !file.exists()) {
+                throw new FileNotFoundException("File doesn't exist: " + file);
+            } else {
+                throw new ZipException("File too short to be a zip file: " + file.length());
+            }
         }
         String name = file.getPath();
 
@@ -771,6 +778,14 @@
         return locsig;
     }
 
+    /** @hide */
+    // @VisibleForTesting
+    public int getFileDescriptor() {
+        return getFileDescriptor(jzfile);
+    }
+
+    private static native int getFileDescriptor(long jzfile);
+
     private static native long open(String name, int mode, long lastModified,
                                     boolean usemmap) throws IOException;
     private static native int getTotal(long jzfile);
diff --git a/ojluni/src/main/java/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java b/ojluni/src/main/java/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java
deleted file mode 100755
index 05a6174..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (c) 2001, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.net.www.protocol.https;
-
-import java.net.URL;
-import java.net.Proxy;
-import java.net.SecureCacheResponse;
-import java.security.Principal;
-import java.io.IOException;
-import java.util.List;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import sun.net.www.http.*;
-import sun.net.www.protocol.http.HttpURLConnection;
-
-/**
- * HTTPS URL connection support.
- * We need this delegate because HttpsURLConnection is a subclass of
- * java.net.HttpURLConnection. We will avoid copying over the code from
- * sun.net.www.protocol.http.HttpURLConnection by having this class
- *
- */
-public abstract class AbstractDelegateHttpsURLConnection extends
-        HttpURLConnection {
-
-    protected AbstractDelegateHttpsURLConnection(URL url,
-            sun.net.www.protocol.http.Handler handler) throws IOException {
-        this(url, null, handler);
-    }
-
-    protected AbstractDelegateHttpsURLConnection(URL url, Proxy p,
-            sun.net.www.protocol.http.Handler handler) throws IOException {
-        super(url, p, handler);
-    }
-
-    protected abstract javax.net.ssl.SSLSocketFactory getSSLSocketFactory();
-
-    protected abstract javax.net.ssl.HostnameVerifier getHostnameVerifier();
-
-    /**
-     * No user application is able to call these routines, as no one
-     * should ever get access to an instance of
-     * DelegateHttpsURLConnection (sun.* or com.*)
-     */
-
-    /**
-     * Create a new HttpClient object, bypassing the cache of
-     * HTTP client objects/connections.
-     *
-     * Note: this method is changed from protected to public because
-     * the com.sun.ssl.internal.www.protocol.https handler reuses this
-     * class for its actual implemantation
-     *
-     * @param url the URL being accessed
-     */
-    public void setNewClient (URL url)
-        throws IOException {
-        setNewClient (url, false);
-    }
-
-    /**
-     * Obtain a HttpClient object. Use the cached copy if specified.
-     *
-     * Note: this method is changed from protected to public because
-     * the com.sun.ssl.internal.www.protocol.https handler reuses this
-     * class for its actual implemantation
-     *
-     * @param url       the URL being accessed
-     * @param useCache  whether the cached connection should be used
-     *        if present
-     */
-    public void setNewClient (URL url, boolean useCache)
-        throws IOException {
-        http = HttpsClient.New (getSSLSocketFactory(),
-                                url,
-                                getHostnameVerifier(),
-                                useCache, this);
-        ((HttpsClient)http).afterConnect();
-    }
-
-    /**
-     * Create a new HttpClient object, set up so that it uses
-     * per-instance proxying to the given HTTP proxy.  This
-     * bypasses the cache of HTTP client objects/connections.
-     *
-     * Note: this method is changed from protected to public because
-     * the com.sun.ssl.internal.www.protocol.https handler reuses this
-     * class for its actual implemantation
-     *
-     * @param url       the URL being accessed
-     * @param proxyHost the proxy host to use
-     * @param proxyPort the proxy port to use
-     */
-    public void setProxiedClient (URL url, String proxyHost, int proxyPort)
-            throws IOException {
-        setProxiedClient(url, proxyHost, proxyPort, false);
-    }
-
-    /**
-     * Obtain a HttpClient object, set up so that it uses per-instance
-     * proxying to the given HTTP proxy. Use the cached copy of HTTP
-     * client objects/connections if specified.
-     *
-     * Note: this method is changed from protected to public because
-     * the com.sun.ssl.internal.www.protocol.https handler reuses this
-     * class for its actual implemantation
-     *
-     * @param url       the URL being accessed
-     * @param proxyHost the proxy host to use
-     * @param proxyPort the proxy port to use
-     * @param useCache  whether the cached connection should be used
-     *        if present
-     */
-    public void setProxiedClient (URL url, String proxyHost, int proxyPort,
-            boolean useCache) throws IOException {
-        proxiedConnect(url, proxyHost, proxyPort, useCache);
-        if (!http.isCachedConnection()) {
-            doTunneling();
-        }
-        ((HttpsClient)http).afterConnect();
-    }
-
-    protected void proxiedConnect(URL url, String proxyHost, int proxyPort,
-            boolean useCache) throws IOException {
-        if (connected)
-            return;
-        http = HttpsClient.New (getSSLSocketFactory(),
-                                url,
-                                getHostnameVerifier(),
-                                proxyHost, proxyPort, useCache, this);
-        connected = true;
-    }
-
-    /**
-     * Used by subclass to access "connected" variable.
-     */
-    public boolean isConnected() {
-        return connected;
-    }
-
-    /**
-     * Used by subclass to access "connected" variable.
-     */
-    public void setConnected(boolean conn) {
-        connected = conn;
-    }
-
-    /**
-     * Implements the HTTP protocol handler's "connect" method,
-     * establishing an SSL connection to the server as necessary.
-     */
-    public void connect() throws IOException {
-        if (connected)
-            return;
-        plainConnect();
-        if (cachedResponse != null) {
-            // using cached response
-            return;
-        }
-        if (!http.isCachedConnection() && http.needsTunneling()) {
-            doTunneling();
-        }
-        ((HttpsClient)http).afterConnect();
-    }
-
-    // will try to use cached HttpsClient
-    protected HttpClient getNewHttpClient(URL url, Proxy p, int connectTimeout)
-        throws IOException {
-        return HttpsClient.New(getSSLSocketFactory(), url,
-                               getHostnameVerifier(), p, true, connectTimeout,
-                               this);
-    }
-
-    // will open new connection
-    protected HttpClient getNewHttpClient(URL url, Proxy p, int connectTimeout,
-                                          boolean useCache)
-        throws IOException {
-        return HttpsClient.New(getSSLSocketFactory(), url,
-                               getHostnameVerifier(), p,
-                               useCache, connectTimeout, this);
-    }
-
-    /**
-     * Returns the cipher suite in use on this connection.
-     */
-    public String getCipherSuite () {
-        if (cachedResponse != null) {
-            return ((SecureCacheResponse)cachedResponse).getCipherSuite();
-        }
-        if (http == null) {
-            throw new IllegalStateException("connection not yet open");
-        } else {
-           return ((HttpsClient)http).getCipherSuite ();
-        }
-    }
-
-    /**
-     * Returns the certificate chain the client sent to the
-     * server, or null if the client did not authenticate.
-     */
-    public java.security.cert.Certificate[] getLocalCertificates() {
-        if (cachedResponse != null) {
-            List l = ((SecureCacheResponse)cachedResponse).getLocalCertificateChain();
-            if (l == null) {
-                return null;
-            } else {
-                return (java.security.cert.Certificate[])l.toArray();
-            }
-        }
-        if (http == null) {
-            throw new IllegalStateException("connection not yet open");
-        } else {
-            return (((HttpsClient)http).getLocalCertificates ());
-        }
-    }
-
-    /**
-     * Returns the server's certificate chain, or throws
-     * SSLPeerUnverified Exception if
-     * the server did not authenticate.
-     */
-    public java.security.cert.Certificate[] getServerCertificates()
-            throws SSLPeerUnverifiedException {
-        if (cachedResponse != null) {
-            List l = ((SecureCacheResponse)cachedResponse).getServerCertificateChain();
-            if (l == null) {
-                return null;
-            } else {
-                return (java.security.cert.Certificate[])l.toArray();
-            }
-        }
-
-        if (http == null) {
-            throw new IllegalStateException("connection not yet open");
-        } else {
-            return (((HttpsClient)http).getServerCertificates ());
-        }
-    }
-
-    /**
-     * Returns the server's X.509 certificate chain, or null if
-     * the server did not authenticate.
-     */
-    public javax.security.cert.X509Certificate[] getServerCertificateChain()
-            throws SSLPeerUnverifiedException {
-        if (cachedResponse != null) {
-            throw new UnsupportedOperationException("this method is not supported when using cache");
-        }
-        if (http == null) {
-            throw new IllegalStateException("connection not yet open");
-        } else {
-            return ((HttpsClient)http).getServerCertificateChain ();
-        }
-    }
-
-    /**
-     * Returns the server's principal, or throws SSLPeerUnverifiedException
-     * if the server did not authenticate.
-     */
-    Principal getPeerPrincipal()
-            throws SSLPeerUnverifiedException
-    {
-        if (cachedResponse != null) {
-            return ((SecureCacheResponse)cachedResponse).getPeerPrincipal();
-        }
-
-        if (http == null) {
-            throw new IllegalStateException("connection not yet open");
-        } else {
-            return (((HttpsClient)http).getPeerPrincipal());
-        }
-    }
-
-    /**
-     * Returns the principal the client sent to the
-     * server, or null if the client did not authenticate.
-     */
-    Principal getLocalPrincipal()
-    {
-        if (cachedResponse != null) {
-            return ((SecureCacheResponse)cachedResponse).getLocalPrincipal();
-        }
-
-        if (http == null) {
-            throw new IllegalStateException("connection not yet open");
-        } else {
-            return (((HttpsClient)http).getLocalPrincipal());
-        }
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/https/DelegateHttpsURLConnection.java b/ojluni/src/main/java/sun/net/www/protocol/https/DelegateHttpsURLConnection.java
deleted file mode 100755
index b6ff7b4..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/https/DelegateHttpsURLConnection.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.net.www.protocol.https;
-
-import java.net.URL;
-import java.net.Proxy;
-import java.io.IOException;
-
-/**
- * This class was introduced to provide an additional level of
- * abstraction between javax.net.ssl.HttpURLConnection and
- * com.sun.net.ssl.HttpURLConnection objects. <p>
- *
- * javax.net.ssl.HttpURLConnection is used in the new sun.net version
- * of protocol implementation (this one)
- * com.sun.net.ssl.HttpURLConnection is used in the com.sun version.
- *
- */
-public class DelegateHttpsURLConnection extends AbstractDelegateHttpsURLConnection {
-
-    // we need a reference to the HttpsURLConnection to get
-    // the properties set there
-    // we also need it to be public so that it can be referenced
-    // from sun.net.www.protocol.http.HttpURLConnection
-    // this is for ResponseCache.put(URI, URLConnection)
-    // second parameter needs to be cast to javax.net.ssl.HttpsURLConnection
-    // instead of AbstractDelegateHttpsURLConnection
-    public javax.net.ssl.HttpsURLConnection httpsURLConnection;
-
-    DelegateHttpsURLConnection(URL url,
-            sun.net.www.protocol.http.Handler handler,
-            javax.net.ssl.HttpsURLConnection httpsURLConnection)
-            throws IOException {
-        this(url, null, handler, httpsURLConnection);
-    }
-
-    DelegateHttpsURLConnection(URL url, Proxy p,
-            sun.net.www.protocol.http.Handler handler,
-            javax.net.ssl.HttpsURLConnection httpsURLConnection)
-            throws IOException {
-        super(url, p, handler);
-        this.httpsURLConnection = httpsURLConnection;
-    }
-
-    protected javax.net.ssl.SSLSocketFactory getSSLSocketFactory() {
-        return httpsURLConnection.getSSLSocketFactory();
-    }
-
-    protected javax.net.ssl.HostnameVerifier getHostnameVerifier() {
-        return httpsURLConnection.getHostnameVerifier();
-    }
-
-    /*
-     * Called by layered delegator's finalize() method to handle closing
-     * the underlying object.
-     */
-    protected void dispose() throws Throwable {
-        super.finalize();
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/https/Handler.java b/ojluni/src/main/java/sun/net/www/protocol/https/Handler.java
deleted file mode 100755
index d2be7fd..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/https/Handler.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*-
- *      HTTP stream opener
- */
-
-package sun.net.www.protocol.https;
-
-import java.io.IOException;
-import java.net.URL;
-import java.net.Proxy;
-
-/** open an http input stream given a URL */
-public class Handler extends sun.net.www.protocol.http.Handler {
-    protected String proxy;
-    protected int proxyPort;
-
-    protected int getDefaultPort() {
-        return 443;
-    }
-
-    public Handler () {
-        proxy = null;
-        proxyPort = -1;
-    }
-
-    public Handler (String proxy, int port) {
-        this.proxy = proxy;
-        this.proxyPort = port;
-    }
-
-    protected java.net.URLConnection openConnection(URL u)
-    throws IOException {
-        return openConnection(u, (Proxy)null);
-    }
-
-    protected java.net.URLConnection openConnection(URL u, Proxy p)
-        throws IOException {
-        return new HttpsURLConnectionImpl(u, p, this);
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/https/HttpsClient.java b/ojluni/src/main/java/sun/net/www/protocol/https/HttpsClient.java
deleted file mode 100755
index 91a5329..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/https/HttpsClient.java
+++ /dev/null
@@ -1,795 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.net.www.protocol.https;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.io.PrintStream;
-import java.io.BufferedOutputStream;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.net.InetSocketAddress;
-import java.net.Proxy;
-import java.security.Principal;
-import java.security.cert.*;
-import java.util.StringTokenizer;
-import java.util.Vector;
-import java.security.AccessController;
-
-import javax.security.auth.x500.X500Principal;
-
-import javax.net.ssl.*;
-import sun.net.www.http.HttpClient;
-import sun.net.www.protocol.http.HttpURLConnection;
-import sun.security.action.*;
-
-import sun.security.util.HostnameChecker;
-import sun.security.ssl.SSLSocketImpl;
-
-import sun.util.logging.PlatformLogger;
-import static sun.net.www.protocol.http.HttpURLConnection.TunnelState.*;
-
-
-/**
- * This class provides HTTPS client URL support, building on the standard
- * "sun.net.www" HTTP protocol handler.  HTTPS is the same protocol as HTTP,
- * but differs in the transport layer which it uses:  <UL>
- *
- *      <LI>There's a <em>Secure Sockets Layer</em> between TCP
- *      and the HTTP protocol code.
- *
- *      <LI>It uses a different default TCP port.
- *
- *      <LI>It doesn't use application level proxies, which can see and
- *      manipulate HTTP user level data, compromising privacy.  It uses
- *      low level tunneling instead, which hides HTTP protocol and data
- *      from all third parties.  (Traffic analysis is still possible).
- *
- *      <LI>It does basic server authentication, to protect
- *      against "URL spoofing" attacks.  This involves deciding
- *      whether the X.509 certificate chain identifying the server
- *      is trusted, and verifying that the name of the server is
- *      found in the certificate.  (The application may enable an
- *      anonymous SSL cipher suite, and such checks are not done
- *      for anonymous ciphers.)
- *
- *      <LI>It exposes key SSL session attributes, specifically the
- *      cipher suite in use and the server's X509 certificates, to
- *      application software which knows about this protocol handler.
- *
- *      </UL>
- *
- * <P> System properties used include:  <UL>
- *
- *      <LI><em>https.proxyHost</em> ... the host supporting SSL
- *      tunneling using the conventional CONNECT syntax
- *
- *      <LI><em>https.proxyPort</em> ... port to use on proxyHost
- *
- *      <LI><em>https.cipherSuites</em> ... comma separated list of
- *      SSL cipher suite names to enable.
- *
- *      <LI><em>http.nonProxyHosts</em> ...
- *
- *      </UL>
- *
- * @author David Brownell
- * @author Bill Foote
- */
-
-// final for export control reasons (access to APIs); remove with care
-final class HttpsClient extends HttpClient
-    implements HandshakeCompletedListener
-{
-    // STATIC STATE and ACCESSORS THERETO
-
-    // HTTPS uses a different default port number than HTTP.
-    private static final int    httpsPortNumber = 443;
-
-    // default HostnameVerifier class canonical name
-    private static final String defaultHVCanonicalName =
-            "javax.net.ssl.DefaultHostnameVerifier";
-
-    /** Returns the default HTTPS port (443) */
-    @Override
-    protected int getDefaultPort() { return httpsPortNumber; }
-
-    private HostnameVerifier hv;
-    private SSLSocketFactory sslSocketFactory;
-
-    // HttpClient.proxyDisabled will always be false, because we don't
-    // use an application-level HTTP proxy.  We might tunnel through
-    // our http proxy, though.
-
-
-    // INSTANCE DATA
-
-    // last negotiated SSL session
-    private SSLSession  session;
-
-    private String [] getCipherSuites() {
-        //
-        // If ciphers are assigned, sort them into an array.
-        //
-        String ciphers [];
-        String cipherString = AccessController.doPrivileged(
-                new GetPropertyAction("https.cipherSuites"));
-
-        if (cipherString == null || "".equals(cipherString)) {
-            ciphers = null;
-        } else {
-            StringTokenizer     tokenizer;
-            Vector<String>      v = new Vector<String>();
-
-            tokenizer = new StringTokenizer(cipherString, ",");
-            while (tokenizer.hasMoreTokens())
-                v.addElement(tokenizer.nextToken());
-            ciphers = new String [v.size()];
-            for (int i = 0; i < ciphers.length; i++)
-                ciphers [i] = v.elementAt(i);
-        }
-        return ciphers;
-    }
-
-    private String [] getProtocols() {
-        //
-        // If protocols are assigned, sort them into an array.
-        //
-        String protocols [];
-        String protocolString = AccessController.doPrivileged(
-                new GetPropertyAction("https.protocols"));
-
-        if (protocolString == null || "".equals(protocolString)) {
-            protocols = null;
-        } else {
-            StringTokenizer     tokenizer;
-            Vector<String>      v = new Vector<String>();
-
-            tokenizer = new StringTokenizer(protocolString, ",");
-            while (tokenizer.hasMoreTokens())
-                v.addElement(tokenizer.nextToken());
-            protocols = new String [v.size()];
-            for (int i = 0; i < protocols.length; i++) {
-                protocols [i] = v.elementAt(i);
-            }
-        }
-        return protocols;
-    }
-
-    private String getUserAgent() {
-        String userAgent = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction("https.agent"));
-        if (userAgent == null || userAgent.length() == 0) {
-            userAgent = "JSSE";
-        }
-        return userAgent;
-    }
-
-    // should remove once HttpClient.newHttpProxy is putback
-    private static Proxy newHttpProxy(String proxyHost, int proxyPort) {
-        InetSocketAddress saddr = null;
-        final String phost = proxyHost;
-        final int pport = proxyPort < 0 ? httpsPortNumber : proxyPort;
-        try {
-            saddr = java.security.AccessController.doPrivileged(new
-                java.security.PrivilegedExceptionAction<InetSocketAddress>() {
-                public InetSocketAddress run() {
-                    return new InetSocketAddress(phost, pport);
-                }});
-        } catch (java.security.PrivilegedActionException pae) {
-        }
-        return new Proxy(Proxy.Type.HTTP, saddr);
-    }
-
-    // CONSTRUCTOR, FACTORY
-
-
-    /**
-     * Create an HTTPS client URL.  Traffic will be tunneled through any
-     * intermediate nodes rather than proxied, so that confidentiality
-     * of data exchanged can be preserved.  However, note that all the
-     * anonymous SSL flavors are subject to "person-in-the-middle"
-     * attacks against confidentiality.  If you enable use of those
-     * flavors, you may be giving up the protection you get through
-     * SSL tunneling.
-     *
-     * Use New to get new HttpsClient. This constructor is meant to be
-     * used only by New method. New properly checks for URL spoofing.
-     *
-     * @param URL https URL with which a connection must be established
-     */
-    private HttpsClient(SSLSocketFactory sf, URL url)
-    throws IOException
-    {
-        // HttpClient-level proxying is always disabled,
-        // because we override doConnect to do tunneling instead.
-        this(sf, url, (String)null, -1);
-    }
-
-    /**
-     *  Create an HTTPS client URL.  Traffic will be tunneled through
-     * the specified proxy server.
-     */
-    HttpsClient(SSLSocketFactory sf, URL url, String proxyHost, int proxyPort)
-        throws IOException {
-        this(sf, url, proxyHost, proxyPort, -1);
-    }
-
-    /**
-     *  Create an HTTPS client URL.  Traffic will be tunneled through
-     * the specified proxy server, with a connect timeout
-     */
-    HttpsClient(SSLSocketFactory sf, URL url, String proxyHost, int proxyPort,
-                int connectTimeout)
-        throws IOException {
-        this(sf, url,
-             (proxyHost == null? null:
-                HttpsClient.newHttpProxy(proxyHost, proxyPort)),
-                connectTimeout);
-    }
-
-    /**
-     *  Same as previous constructor except using a Proxy
-     */
-    HttpsClient(SSLSocketFactory sf, URL url, Proxy proxy,
-                int connectTimeout)
-        throws IOException {
-        this.proxy = proxy;
-        setSSLSocketFactory(sf);
-        this.proxyDisabled = true;
-
-        this.host = url.getHost();
-        this.url = url;
-        port = url.getPort();
-        if (port == -1) {
-            port = getDefaultPort();
-        }
-        setConnectTimeout(connectTimeout);
-        openServer();
-    }
-
-
-    // This code largely ripped off from HttpClient.New, and
-    // it uses the same keepalive cache.
-
-    static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
-                          HttpURLConnection httpuc)
-            throws IOException {
-        return HttpsClient.New(sf, url, hv, true, httpuc);
-    }
-
-    /** See HttpClient for the model for this method. */
-    static HttpClient New(SSLSocketFactory sf, URL url,
-            HostnameVerifier hv, boolean useCache,
-            HttpURLConnection httpuc) throws IOException {
-        return HttpsClient.New(sf, url, hv, (String)null, -1, useCache, httpuc);
-    }
-
-    /**
-     * Get a HTTPS client to the URL.  Traffic will be tunneled through
-     * the specified proxy server.
-     */
-    static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
-                           String proxyHost, int proxyPort,
-                           HttpURLConnection httpuc) throws IOException {
-        return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, true, httpuc);
-    }
-
-    static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
-                           String proxyHost, int proxyPort, boolean useCache,
-                           HttpURLConnection httpuc)
-        throws IOException {
-        return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, useCache, -1,
-                               httpuc);
-    }
-
-    static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
-                          String proxyHost, int proxyPort, boolean useCache,
-                          int connectTimeout, HttpURLConnection httpuc)
-        throws IOException {
-
-        return HttpsClient.New(sf, url, hv,
-                               (proxyHost == null? null :
-                                HttpsClient.newHttpProxy(proxyHost, proxyPort)),
-                               useCache, connectTimeout, httpuc);
-    }
-
-    static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
-                          Proxy p, boolean useCache,
-                          int connectTimeout, HttpURLConnection httpuc)
-        throws IOException
-    {
-        if (p == null) {
-            p = Proxy.NO_PROXY;
-        }
-        HttpsClient ret = null;
-        if (useCache) {
-            /* see if one's already around */
-            ret = (HttpsClient) kac.get(url, sf);
-            if (ret != null && httpuc != null &&
-                httpuc.streaming() &&
-                httpuc.getRequestMethod() == "POST") {
-                if (!ret.available())
-                    ret = null;
-            }
-
-            if (ret != null) {
-                if ((ret.proxy != null && ret.proxy.equals(p)) ||
-                    (ret.proxy == null && p == null)) {
-                    synchronized (ret) {
-                        ret.cachedHttpClient = true;
-                        assert ret.inCache;
-                        ret.inCache = false;
-                        if (httpuc != null && ret.needsTunneling())
-                            httpuc.setTunnelState(TUNNELING);
-                        PlatformLogger logger = HttpURLConnection.getHttpLogger();
-                        if (logger.isLoggable(PlatformLogger.FINEST)) {
-                            logger.finest("KeepAlive stream retrieved from the cache, " + ret);
-                        }
-                    }
-                } else {
-                    // We cannot return this connection to the cache as it's
-                    // KeepAliveTimeout will get reset. We simply close the connection.
-                    // This should be fine as it is very rare that a connection
-                    // to the same host will not use the same proxy.
-                    synchronized(ret) {
-                        ret.inCache = false;
-                        ret.closeServer();
-                    }
-                    ret = null;
-                }
-            }
-        }
-        if (ret == null) {
-            ret = new HttpsClient(sf, url, p, connectTimeout);
-        } else {
-            SecurityManager security = System.getSecurityManager();
-            if (security != null) {
-                if (ret.proxy == Proxy.NO_PROXY || ret.proxy == null) {
-                    security.checkConnect(InetAddress.getByName(url.getHost()).getHostAddress(), url.getPort());
-                } else {
-                    security.checkConnect(url.getHost(), url.getPort());
-                }
-            }
-            ret.url = url;
-        }
-        ret.setHostnameVerifier(hv);
-
-        return ret;
-    }
-
-    // METHODS
-    void setHostnameVerifier(HostnameVerifier hv) {
-        this.hv = hv;
-    }
-
-    void setSSLSocketFactory(SSLSocketFactory sf) {
-        sslSocketFactory = sf;
-    }
-
-    SSLSocketFactory getSSLSocketFactory() {
-        return sslSocketFactory;
-    }
-
-    /**
-     * The following method, createSocket, is defined in NetworkClient
-     * and overridden here so that the socket facroty is used to create
-     * new sockets.
-     */
-    @Override
-    protected Socket createSocket() throws IOException {
-        try {
-            return sslSocketFactory.createSocket();
-        } catch (SocketException se) {
-            //
-            // bug 6771432
-            // javax.net.SocketFactory throws a SocketException with an
-            // UnsupportedOperationException as its cause to indicate that
-            // unconnected sockets have not been implemented.
-            //
-            Throwable t = se.getCause();
-            if (t != null && t instanceof UnsupportedOperationException) {
-                return super.createSocket();
-            } else {
-                throw se;
-            }
-        }
-    }
-
-
-    @Override
-    public boolean needsTunneling() {
-        return (proxy != null && proxy.type() != Proxy.Type.DIRECT
-                && proxy.type() != Proxy.Type.SOCKS);
-    }
-
-    @Override
-    public void afterConnect() throws IOException, UnknownHostException {
-        if (!isCachedConnection()) {
-            SSLSocket s = null;
-            SSLSocketFactory factory = sslSocketFactory;
-            try {
-                if (!(serverSocket instanceof SSLSocket)) {
-                    s = (SSLSocket)factory.createSocket(serverSocket,
-                                                        host, port, true);
-                } else {
-                    s = (SSLSocket)serverSocket;
-                    if (s instanceof SSLSocketImpl) {
-                        ((SSLSocketImpl)s).setHost(host);
-                    }
-                }
-            } catch (IOException ex) {
-                // If we fail to connect through the tunnel, try it
-                // locally, as a last resort.  If this doesn't work,
-                // throw the original exception.
-                try {
-                    s = (SSLSocket)factory.createSocket(host, port);
-                } catch (IOException ignored) {
-                    throw ex;
-                }
-            }
-
-            //
-            // Force handshaking, so that we get any authentication.
-            // Register a handshake callback so our session state tracks any
-            // later session renegotiations.
-            //
-            String [] protocols = getProtocols();
-            String [] ciphers = getCipherSuites();
-            if (protocols != null) {
-                s.setEnabledProtocols(protocols);
-            }
-            if (ciphers != null) {
-                s.setEnabledCipherSuites(ciphers);
-            }
-            s.addHandshakeCompletedListener(this);
-
-            // We have two hostname verification approaches. One is in
-            // SSL/TLS socket layer, where the algorithm is configured with
-            // SSLParameters.setEndpointIdentificationAlgorithm(), and the
-            // hostname verification is done by X509ExtendedTrustManager when
-            // the algorithm is "HTTPS". The other one is in HTTPS layer,
-            // where the algorithm is customized by
-            // HttpsURLConnection.setHostnameVerifier(), and the hostname
-            // verification is done by HostnameVerifier when the default
-            // rules for hostname verification fail.
-            //
-            // The relationship between two hostname verification approaches
-            // likes the following:
-            //
-            //               |             EIA algorithm
-            //               +----------------------------------------------
-            //               |     null      |   HTTPS    |   LDAP/other   |
-            // -------------------------------------------------------------
-            //     |         |1              |2           |3               |
-            // HNV | default | Set HTTPS EIA | use EIA    | HTTPS          |
-            //     |--------------------------------------------------------
-            //     | non -   |4              |5           |6               |
-            //     | default | HTTPS/HNV     | use EIA    | HTTPS/HNV      |
-            // -------------------------------------------------------------
-            //
-            // Abbreviation:
-            //     EIA: the endpoint identification algorithm in SSL/TLS
-            //           socket layer
-            //     HNV: the hostname verification object in HTTPS layer
-            // Notes:
-            //     case 1. default HNV and EIA is null
-            //           Set EIA as HTTPS, hostname check done in SSL/TLS
-            //           layer.
-            //     case 2. default HNV and EIA is HTTPS
-            //           Use existing EIA, hostname check done in SSL/TLS
-            //           layer.
-            //     case 3. default HNV and EIA is other than HTTPS
-            //           Use existing EIA, EIA check done in SSL/TLS
-            //           layer, then do HTTPS check in HTTPS layer.
-            //     case 4. non-default HNV and EIA is null
-            //           No EIA, no EIA check done in SSL/TLS layer, then do
-            //           HTTPS check in HTTPS layer using HNV as override.
-            //     case 5. non-default HNV and EIA is HTTPS
-            //           Use existing EIA, hostname check done in SSL/TLS
-            //           layer. No HNV override possible. We will review this
-            //           decision and may update the architecture for JDK 7.
-            //     case 6. non-default HNV and EIA is other than HTTPS
-            //           Use existing EIA, EIA check done in SSL/TLS layer,
-            //           then do HTTPS check in HTTPS layer as override.
-            boolean needToCheckSpoofing = true;
-            String identification =
-                s.getSSLParameters().getEndpointIdentificationAlgorithm();
-            if (identification != null && identification.length() != 0) {
-                if (identification.equalsIgnoreCase("HTTPS")) {
-                    // Do not check server identity again out of SSLSocket,
-                    // the endpoint will be identified during TLS handshaking
-                    // in SSLSocket.
-                    needToCheckSpoofing = false;
-                }   // else, we don't understand the identification algorithm,
-                    // need to check URL spoofing here.
-            } else {
-                boolean isDefaultHostnameVerifier = false;
-
-                // We prefer to let the SSLSocket do the spoof checks, but if
-                // the application has specified a HostnameVerifier (HNV),
-                // we will always use that.
-                if (hv != null) {
-                    String canonicalName = hv.getClass().getCanonicalName();
-                    if (canonicalName != null &&
-                    canonicalName.equalsIgnoreCase(defaultHVCanonicalName)) {
-                        isDefaultHostnameVerifier = true;
-                    }
-                } else {
-                    // Unlikely to happen! As the behavior is the same as the
-                    // default hostname verifier, so we prefer to let the
-                    // SSLSocket do the spoof checks.
-                    isDefaultHostnameVerifier = true;
-                }
-
-                if (isDefaultHostnameVerifier) {
-                    // If the HNV is the default from HttpsURLConnection, we
-                    // will do the spoof checks in SSLSocket.
-                    SSLParameters paramaters = s.getSSLParameters();
-                    paramaters.setEndpointIdentificationAlgorithm("HTTPS");
-                    s.setSSLParameters(paramaters);
-
-                    needToCheckSpoofing = false;
-                }
-            }
-
-            s.startHandshake();
-            session = s.getSession();
-            // change the serverSocket and serverOutput
-            serverSocket = s;
-            try {
-                serverOutput = new PrintStream(
-                    new BufferedOutputStream(serverSocket.getOutputStream()),
-                    false, encoding);
-            } catch (UnsupportedEncodingException e) {
-                throw new InternalError(encoding+" encoding not found");
-            }
-
-            // check URL spoofing if it has not been checked under handshaking
-            if (needToCheckSpoofing) {
-                checkURLSpoofing(hv);
-            }
-        } else {
-            // if we are reusing a cached https session,
-            // we don't need to do handshaking etc. But we do need to
-            // set the ssl session
-            session = ((SSLSocket)serverSocket).getSession();
-        }
-    }
-
-    // Server identity checking is done according to RFC 2818: HTTP over TLS
-    // Section 3.1 Server Identity
-    private void checkURLSpoofing(HostnameVerifier hostnameVerifier)
-            throws IOException {
-        //
-        // Get authenticated server name, if any
-        //
-        String host = url.getHost();
-
-        // if IPv6 strip off the "[]"
-        if (host != null && host.startsWith("[") && host.endsWith("]")) {
-            host = host.substring(1, host.length()-1);
-        }
-
-        Certificate[] peerCerts = null;
-        String cipher = session.getCipherSuite();
-        try {
-            HostnameChecker checker = HostnameChecker.getInstance(
-                                                HostnameChecker.TYPE_TLS);
-
-            // Use ciphersuite to determine whether Kerberos is present.
-            if (cipher.startsWith("TLS_KRB5")) {
-                if (!HostnameChecker.match(host, getPeerPrincipal())) {
-                    throw new SSLPeerUnverifiedException("Hostname checker" +
-                                " failed for Kerberos");
-                }
-            } else { // X.509
-
-                // get the subject's certificate
-                peerCerts = session.getPeerCertificates();
-
-                X509Certificate peerCert;
-                if (peerCerts[0] instanceof
-                        java.security.cert.X509Certificate) {
-                    peerCert = (java.security.cert.X509Certificate)peerCerts[0];
-                } else {
-                    throw new SSLPeerUnverifiedException("");
-                }
-                checker.match(host, peerCert);
-            }
-
-            // if it doesn't throw an exception, we passed. Return.
-            return;
-
-        } catch (SSLPeerUnverifiedException e) {
-
-            //
-            // client explicitly changed default policy and enabled
-            // anonymous ciphers; we can't check the standard policy
-            //
-            // ignore
-        } catch (java.security.cert.CertificateException cpe) {
-            // ignore
-        }
-
-        if ((cipher != null) && (cipher.indexOf("_anon_") != -1)) {
-            return;
-        } else if ((hostnameVerifier != null) &&
-                   (hostnameVerifier.verify(host, session))) {
-            return;
-        }
-
-        serverSocket.close();
-        session.invalidate();
-
-        throw new IOException("HTTPS hostname wrong:  should be <"
-                              + url.getHost() + ">");
-    }
-
-    @Override
-    protected void putInKeepAliveCache() {
-        if (inCache) {
-            assert false : "Duplicate put to keep alive cache";
-            return;
-        }
-        inCache = true;
-        kac.put(url, sslSocketFactory, this);
-    }
-
-    /*
-     * Close an idle connection to this URL (if it exists in the cache).
-     */
-    @Override
-    public void closeIdleConnection() {
-        HttpClient http = (HttpClient) kac.get(url, sslSocketFactory);
-        if (http != null) {
-            http.closeServer();
-        }
-    }
-
-    /**
-     * Returns the cipher suite in use on this connection.
-     */
-    String getCipherSuite() {
-        return session.getCipherSuite();
-    }
-
-    /**
-     * Returns the certificate chain the client sent to the
-     * server, or null if the client did not authenticate.
-     */
-    public java.security.cert.Certificate [] getLocalCertificates() {
-        return session.getLocalCertificates();
-    }
-
-    /**
-     * Returns the certificate chain with which the server
-     * authenticated itself, or throw a SSLPeerUnverifiedException
-     * if the server did not authenticate.
-     */
-    java.security.cert.Certificate [] getServerCertificates()
-            throws SSLPeerUnverifiedException
-    {
-        return session.getPeerCertificates();
-    }
-
-    /**
-     * Returns the X.509 certificate chain with which the server
-     * authenticated itself, or null if the server did not authenticate.
-     */
-    javax.security.cert.X509Certificate [] getServerCertificateChain()
-            throws SSLPeerUnverifiedException
-    {
-        return session.getPeerCertificateChain();
-    }
-
-    /**
-     * Returns the principal with which the server authenticated
-     * itself, or throw a SSLPeerUnverifiedException if the
-     * server did not authenticate.
-     */
-    Principal getPeerPrincipal()
-            throws SSLPeerUnverifiedException
-    {
-        Principal principal;
-        try {
-            principal = session.getPeerPrincipal();
-        } catch (AbstractMethodError e) {
-            // if the provider does not support it, fallback to peer certs.
-            // return the X500Principal of the end-entity cert.
-            java.security.cert.Certificate[] certs =
-                        session.getPeerCertificates();
-            principal = (X500Principal)
-                ((X509Certificate)certs[0]).getSubjectX500Principal();
-        }
-        return principal;
-    }
-
-    /**
-     * Returns the principal the client sent to the
-     * server, or null if the client did not authenticate.
-     */
-    Principal getLocalPrincipal()
-    {
-        Principal principal;
-        try {
-            principal = session.getLocalPrincipal();
-        } catch (AbstractMethodError e) {
-            principal = null;
-            // if the provider does not support it, fallback to local certs.
-            // return the X500Principal of the end-entity cert.
-            java.security.cert.Certificate[] certs =
-                        session.getLocalCertificates();
-            if (certs != null) {
-                principal = (X500Principal)
-                    ((X509Certificate)certs[0]).getSubjectX500Principal();
-            }
-        }
-        return principal;
-    }
-
-    /**
-     * This method implements the SSL HandshakeCompleted callback,
-     * remembering the resulting session so that it may be queried
-     * for the current cipher suite and peer certificates.  Servers
-     * sometimes re-initiate handshaking, so the session in use on
-     * a given connection may change.  When sessions change, so may
-     * peer identities and cipher suites.
-     */
-    public void handshakeCompleted(HandshakeCompletedEvent event)
-    {
-        session = event.getSession();
-    }
-
-    /**
-     * @return the proxy host being used for this client, or null
-     *          if we're not going through a proxy
-     */
-    @Override
-    public String getProxyHostUsed() {
-        if (!needsTunneling()) {
-            return null;
-        } else {
-            return super.getProxyHostUsed();
-        }
-    }
-
-    /**
-     * @return the proxy port being used for this client.  Meaningless
-     *          if getProxyHostUsed() gives null.
-     */
-    @Override
-    public int getProxyPortUsed() {
-        return (proxy == null || proxy.type() == Proxy.Type.DIRECT ||
-                proxy.type() == Proxy.Type.SOCKS)? -1:
-            ((InetSocketAddress)proxy.address()).getPort();
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/https/HttpsURLConnectionImpl.java b/ojluni/src/main/java/sun/net/www/protocol/https/HttpsURLConnectionImpl.java
deleted file mode 100755
index 832854c..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/https/HttpsURLConnectionImpl.java
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * NOTE: This class lives in the package sun.net.www.protocol.https.
- * There is a copy in com.sun.net.ssl.internal.www.protocol.https for JSSE
- * 1.0.2 compatibility. It is 100% identical except the package and extends
- * lines. Any changes should be made to be class in sun.net.* and then copied
- * to com.sun.net.*.
- */
-
-// For both copies of the file, uncomment one line and comment the other
-package sun.net.www.protocol.https;
-// package com.sun.net.ssl.internal.www.protocol.https;
-
-import java.net.URL;
-import java.net.Proxy;
-import java.net.ProtocolException;
-import java.io.*;
-import javax.net.ssl.*;
-import java.security.Permission;
-import java.security.Principal;
-import java.util.Map;
-import java.util.List;
-import sun.net.www.http.HttpClient;
-
-/**
- * A class to represent an HTTP connection to a remote object.
- *
- * Ideally, this class should subclass and inherit the http handler
- * implementation, but it can't do so because that class have the
- * wrong Java Type.  Thus it uses the delegate (aka, the
- * Adapter/Wrapper design pattern) to reuse code from the http
- * handler.
- *
- * Since it would use a delegate to access
- * sun.net.www.protocol.http.HttpURLConnection functionalities, it
- * needs to implement all public methods in it's super class and all
- * the way to Object.
- *
- */
-
-// For both copies of the file, uncomment one line and comment the
-// other. The differences between the two copies are introduced for
-// plugin, and it is marked as such.
-public class HttpsURLConnectionImpl
-        extends javax.net.ssl.HttpsURLConnection {
-// public class HttpsURLConnectionOldImpl
-//      extends com.sun.net.ssl.HttpsURLConnection {
-
-    // NOTE: made protected for plugin so that subclass can set it.
-    protected DelegateHttpsURLConnection delegate;
-
-// For both copies of the file, uncomment one line and comment the other
-    HttpsURLConnectionImpl(URL u, Handler handler) throws IOException {
-//    HttpsURLConnectionOldImpl(URL u, Handler handler) throws IOException {
-        this(u, null, handler);
-    }
-
-// For both copies of the file, uncomment one line and comment the other
-    HttpsURLConnectionImpl(URL u, Proxy p, Handler handler) throws IOException {
-//    HttpsURLConnectionOldImpl(URL u, Proxy p, Handler handler) throws IOException {
-        super(u);
-        delegate = new DelegateHttpsURLConnection(url, p, handler, this);
-    }
-
-    // NOTE: introduced for plugin
-    // subclass needs to overwrite this to set delegate to
-    // the appropriate delegatee
-    protected HttpsURLConnectionImpl(URL u) throws IOException {
-        super(u);
-    }
-
-    /**
-     * Create a new HttpClient object, bypassing the cache of
-     * HTTP client objects/connections.
-     *
-     * @param url       the URL being accessed
-     */
-    protected void setNewClient(URL url) throws IOException {
-        delegate.setNewClient(url, false);
-    }
-
-    /**
-     * Obtain a HttpClient object. Use the cached copy if specified.
-     *
-     * @param url       the URL being accessed
-     * @param useCache  whether the cached connection should be used
-     *                  if present
-     */
-    protected void setNewClient(URL url, boolean useCache)
-            throws IOException {
-        delegate.setNewClient(url, useCache);
-    }
-
-    /**
-     * Create a new HttpClient object, set up so that it uses
-     * per-instance proxying to the given HTTP proxy.  This
-     * bypasses the cache of HTTP client objects/connections.
-     *
-     * @param url       the URL being accessed
-     * @param proxyHost the proxy host to use
-     * @param proxyPort the proxy port to use
-     */
-    protected void setProxiedClient(URL url, String proxyHost, int proxyPort)
-            throws IOException {
-        delegate.setProxiedClient(url, proxyHost, proxyPort);
-    }
-
-    /**
-     * Obtain a HttpClient object, set up so that it uses per-instance
-     * proxying to the given HTTP proxy. Use the cached copy of HTTP
-     * client objects/connections if specified.
-     *
-     * @param url       the URL being accessed
-     * @param proxyHost the proxy host to use
-     * @param proxyPort the proxy port to use
-     * @param useCache  whether the cached connection should be used
-     *                  if present
-     */
-    protected void setProxiedClient(URL url, String proxyHost, int proxyPort,
-            boolean useCache) throws IOException {
-        delegate.setProxiedClient(url, proxyHost, proxyPort, useCache);
-    }
-
-    /**
-     * Implements the HTTP protocol handler's "connect" method,
-     * establishing an SSL connection to the server as necessary.
-     */
-    public void connect() throws IOException {
-        delegate.connect();
-    }
-
-    /**
-     * Used by subclass to access "connected" variable.  Since we are
-     * delegating the actual implementation to "delegate", we need to
-     * delegate the access of "connected" as well.
-     */
-    protected boolean isConnected() {
-        return delegate.isConnected();
-    }
-
-    /**
-     * Used by subclass to access "connected" variable.  Since we are
-     * delegating the actual implementation to "delegate", we need to
-     * delegate the access of "connected" as well.
-     */
-    protected void setConnected(boolean conn) {
-        delegate.setConnected(conn);
-    }
-
-    /**
-     * Returns the cipher suite in use on this connection.
-     */
-    public String getCipherSuite() {
-        return delegate.getCipherSuite();
-    }
-
-    /**
-     * Returns the certificate chain the client sent to the
-     * server, or null if the client did not authenticate.
-     */
-    public java.security.cert.Certificate []
-        getLocalCertificates() {
-        return delegate.getLocalCertificates();
-    }
-
-    /**
-     * Returns the server's certificate chain, or throws
-     * SSLPeerUnverified Exception if
-     * the server did not authenticate.
-     */
-    public java.security.cert.Certificate []
-        getServerCertificates() throws SSLPeerUnverifiedException {
-        return delegate.getServerCertificates();
-    }
-
-    /**
-     * Returns the server's X.509 certificate chain, or null if
-     * the server did not authenticate.
-     *
-     * NOTE: This method is not necessary for the version of this class
-     * implementing javax.net.ssl.HttpsURLConnection, but provided for
-     * compatibility with the com.sun.net.ssl.HttpsURLConnection version.
-     */
-    public javax.security.cert.X509Certificate[] getServerCertificateChain() {
-        try {
-            return delegate.getServerCertificateChain();
-        } catch (SSLPeerUnverifiedException e) {
-            // this method does not throw an exception as declared in
-            // com.sun.net.ssl.HttpsURLConnection.
-            // Return null for compatibility.
-            return null;
-        }
-    }
-
-    /**
-     * Returns the principal with which the server authenticated itself,
-     * or throw a SSLPeerUnverifiedException if the server did not authenticate.
-     */
-    public Principal getPeerPrincipal()
-            throws SSLPeerUnverifiedException
-    {
-        return delegate.getPeerPrincipal();
-    }
-
-    /**
-     * Returns the principal the client sent to the
-     * server, or null if the client did not authenticate.
-     */
-    public Principal getLocalPrincipal()
-    {
-        return delegate.getLocalPrincipal();
-    }
-
-    /*
-     * Allowable input/output sequences:
-     * [interpreted as POST/PUT]
-     * - get output, [write output,] get input, [read input]
-     * - get output, [write output]
-     * [interpreted as GET]
-     * - get input, [read input]
-     * Disallowed:
-     * - get input, [read input,] get output, [write output]
-     */
-
-    public synchronized OutputStream getOutputStream() throws IOException {
-        return delegate.getOutputStream();
-    }
-
-    public synchronized InputStream getInputStream() throws IOException {
-        return delegate.getInputStream();
-    }
-
-    public InputStream getErrorStream() {
-        return delegate.getErrorStream();
-    }
-
-    /**
-     * Disconnect from the server.
-     */
-    public void disconnect() {
-        delegate.disconnect();
-    }
-
-    public boolean usingProxy() {
-        return delegate.usingProxy();
-    }
-
-    /**
-     * Returns an unmodifiable Map of the header fields.
-     * The Map keys are Strings that represent the
-     * response-header field names. Each Map value is an
-     * unmodifiable List of Strings that represents
-     * the corresponding field values.
-     *
-     * @return a Map of header fields
-     * @since 1.4
-     */
-    public Map<String,List<String>> getHeaderFields() {
-        return delegate.getHeaderFields();
-    }
-
-    /**
-     * Gets a header field by name. Returns null if not known.
-     * @param name the name of the header field
-     */
-    public String getHeaderField(String name) {
-        return delegate.getHeaderField(name);
-    }
-
-    /**
-     * Gets a header field by index. Returns null if not known.
-     * @param n the index of the header field
-     */
-    public String getHeaderField(int n) {
-        return delegate.getHeaderField(n);
-    }
-
-    /**
-     * Gets a header field by index. Returns null if not known.
-     * @param n the index of the header field
-     */
-    public String getHeaderFieldKey(int n) {
-        return delegate.getHeaderFieldKey(n);
-    }
-
-    /**
-     * Sets request property. If a property with the key already
-     * exists, overwrite its value with the new value.
-     * @param value the value to be set
-     */
-    public void setRequestProperty(String key, String value) {
-        delegate.setRequestProperty(key, value);
-    }
-
-    /**
-     * Adds a general request property specified by a
-     * key-value pair.  This method will not overwrite
-     * existing values associated with the same key.
-     *
-     * @param   key     the keyword by which the request is known
-     *                  (e.g., "<code>accept</code>").
-     * @param   value  the value associated with it.
-     * @see #getRequestProperties(java.lang.String)
-     * @since 1.4
-     */
-    public void addRequestProperty(String key, String value) {
-        delegate.addRequestProperty(key, value);
-    }
-
-    /**
-     * Overwrite super class method
-     */
-    public int getResponseCode() throws IOException {
-        return delegate.getResponseCode();
-    }
-
-    public String getRequestProperty(String key) {
-        return delegate.getRequestProperty(key);
-    }
-
-    /**
-     * Returns an unmodifiable Map of general request
-     * properties for this connection. The Map keys
-     * are Strings that represent the request-header
-     * field names. Each Map value is a unmodifiable List
-     * of Strings that represents the corresponding
-     * field values.
-     *
-     * @return  a Map of the general request properties for this connection.
-     * @throws IllegalStateException if already connected
-     * @since 1.4
-     */
-    public Map<String,List<String>> getRequestProperties() {
-        return delegate.getRequestProperties();
-    }
-
-    /*
-     * We support JDK 1.2.x so we can't count on these from JDK 1.3.
-     * We override and supply our own version.
-     */
-    public void setInstanceFollowRedirects(boolean shouldFollow) {
-        delegate.setInstanceFollowRedirects(shouldFollow);
-    }
-
-    public boolean getInstanceFollowRedirects() {
-        return delegate.getInstanceFollowRedirects();
-    }
-
-    public void setRequestMethod(String method) throws ProtocolException {
-        delegate.setRequestMethod(method);
-    }
-
-    public String getRequestMethod() {
-        return delegate.getRequestMethod();
-    }
-
-    public String getResponseMessage() throws IOException {
-        return delegate.getResponseMessage();
-    }
-
-    public long getHeaderFieldDate(String name, long Default) {
-        return delegate.getHeaderFieldDate(name, Default);
-    }
-
-    public Permission getPermission() throws IOException {
-        return delegate.getPermission();
-    }
-
-    public URL getURL() {
-        return delegate.getURL();
-    }
-
-    public int getContentLength() {
-        return delegate.getContentLength();
-    }
-
-    public long getContentLengthLong() {
-        return delegate.getContentLengthLong();
-    }
-
-    public String getContentType() {
-        return delegate.getContentType();
-    }
-
-    public String getContentEncoding() {
-        return delegate.getContentEncoding();
-    }
-
-    public long getExpiration() {
-        return delegate.getExpiration();
-    }
-
-    public long getDate() {
-        return delegate.getDate();
-    }
-
-    public long getLastModified() {
-        return delegate.getLastModified();
-    }
-
-    public int getHeaderFieldInt(String name, int Default) {
-        return delegate.getHeaderFieldInt(name, Default);
-    }
-
-    public long getHeaderFieldLong(String name, long Default) {
-        return delegate.getHeaderFieldLong(name, Default);
-    }
-
-    public Object getContent() throws IOException {
-        return delegate.getContent();
-    }
-
-    public Object getContent(Class[] classes) throws IOException {
-        return delegate.getContent(classes);
-    }
-
-    public String toString() {
-        return delegate.toString();
-    }
-
-    public void setDoInput(boolean doinput) {
-        delegate.setDoInput(doinput);
-    }
-
-    public boolean getDoInput() {
-        return delegate.getDoInput();
-    }
-
-    public void setDoOutput(boolean dooutput) {
-        delegate.setDoOutput(dooutput);
-    }
-
-    public boolean getDoOutput() {
-        return delegate.getDoOutput();
-    }
-
-    public void setAllowUserInteraction(boolean allowuserinteraction) {
-        delegate.setAllowUserInteraction(allowuserinteraction);
-    }
-
-    public boolean getAllowUserInteraction() {
-        return delegate.getAllowUserInteraction();
-    }
-
-    public void setUseCaches(boolean usecaches) {
-        delegate.setUseCaches(usecaches);
-    }
-
-    public boolean getUseCaches() {
-        return delegate.getUseCaches();
-    }
-
-    public void setIfModifiedSince(long ifmodifiedsince) {
-        delegate.setIfModifiedSince(ifmodifiedsince);
-    }
-
-    public long getIfModifiedSince() {
-        return delegate.getIfModifiedSince();
-    }
-
-    public boolean getDefaultUseCaches() {
-        return delegate.getDefaultUseCaches();
-    }
-
-    public void setDefaultUseCaches(boolean defaultusecaches) {
-        delegate.setDefaultUseCaches(defaultusecaches);
-    }
-
-    /*
-     * finalize (dispose) the delegated object.  Otherwise
-     * sun.net.www.protocol.http.HttpURLConnection's finalize()
-     * would have to be made public.
-     */
-    protected void finalize() throws Throwable {
-        delegate.dispose();
-    }
-
-    public boolean equals(Object obj) {
-        return delegate.equals(obj);
-    }
-
-    public int hashCode() {
-        return delegate.hashCode();
-    }
-
-    public void setConnectTimeout(int timeout) {
-        delegate.setConnectTimeout(timeout);
-    }
-
-    public int getConnectTimeout() {
-        return delegate.getConnectTimeout();
-    }
-
-    public void setReadTimeout(int timeout) {
-        delegate.setReadTimeout(timeout);
-    }
-
-    public int getReadTimeout() {
-        return delegate.getReadTimeout();
-    }
-
-    public void setFixedLengthStreamingMode (int contentLength) {
-        delegate.setFixedLengthStreamingMode(contentLength);
-    }
-
-    public void setFixedLengthStreamingMode(long contentLength) {
-        delegate.setFixedLengthStreamingMode(contentLength);
-    }
-
-    public void setChunkedStreamingMode (int chunklen) {
-        delegate.setChunkedStreamingMode(chunklen);
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/pkcs/PKCS7.java b/ojluni/src/main/java/sun/security/pkcs/PKCS7.java
index 4929c01..5fb23ea 100755
--- a/ojluni/src/main/java/sun/security/pkcs/PKCS7.java
+++ b/ojluni/src/main/java/sun/security/pkcs/PKCS7.java
@@ -31,11 +31,17 @@
 import java.util.*;
 import java.security.cert.X509Certificate;
 import java.security.cert.CertificateException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.CertificateParsingException;
 import java.security.cert.X509CRL;
 import java.security.cert.CRLException;
 import java.security.cert.CertificateFactory;
 import java.security.*;
 
+import javax.security.auth.x500.X500Principal;
+
 import sun.security.util.*;
 import sun.security.x509.AlgorithmId;
 import sun.security.x509.CertificateIssuerName;
@@ -201,7 +207,7 @@
     private void parseNetscapeCertChain(DerValue val)
     throws ParsingException, IOException {
         DerInputStream dis = new DerInputStream(val.toByteArray());
-        DerValue[] contents = dis.getSequence(2);
+        DerValue[] contents = dis.getSequence(2, true);
         certificates = new X509Certificate[contents.length];
 
         CertificateFactory certfac = null;
@@ -214,13 +220,14 @@
         for (int i=0; i < contents.length; i++) {
             ByteArrayInputStream bais = null;
             try {
+                byte[] original = contents[i].getOriginalEncodedForm();
                 if (certfac == null)
-                    certificates[i] = new X509CertImpl(contents[i]);
+                    certificates[i] = new X509CertImpl(contents[i], original);
                 else {
-                    byte[] encoded = contents[i].toByteArray();
-                    bais = new ByteArrayInputStream(encoded);
-                    certificates[i] =
-                        (X509Certificate)certfac.generateCertificate(bais);
+                    bais = new ByteArrayInputStream(original);
+                    certificates[i] = new VerbatimX509Certificate(
+                        (X509Certificate)certfac.generateCertificate(bais),
+                        original);
                     bais.close();
                     bais = null;
                 }
@@ -279,7 +286,7 @@
          * (certificates are OPTIONAL)
          */
         if ((byte)(dis.peekByte()) == (byte)0xA0) {
-            DerValue[] certVals = dis.getSet(2, true);
+            DerValue[] certVals = dis.getSet(2, true, true);
 
             len = certVals.length;
             certificates = new X509Certificate[len];
@@ -292,13 +299,14 @@
                     // We only parse the normal certificate. Other types of
                     // CertificateChoices ignored.
                     if (tag == DerValue.tag_Sequence) {
+                        byte[] original = certVals[i].getOriginalEncodedForm();
                         if (certfac == null) {
-                            certificates[count] = new X509CertImpl(certVals[i]);
+                            certificates[count] = new X509CertImpl(certVals[i], original);
                         } else {
-                            byte[] encoded = certVals[i].toByteArray();
-                            bais = new ByteArrayInputStream(encoded);
-                            certificates[count] =
-                                (X509Certificate)certfac.generateCertificate(bais);
+                            bais = new ByteArrayInputStream(original);
+                            certificates[count] = new VerbatimX509Certificate(
+                                (X509Certificate)certfac.generateCertificate(bais),
+                                original);
                             bais.close();
                             bais = null;
                         }
@@ -401,20 +409,21 @@
         } catch (CertificateException ce) {
             // do nothing
         }
-        DerValue[] certVals = dis.getSet(2);
+        DerValue[] certVals = dis.getSet(2, false, true);
         len = certVals.length;
         certificates = new X509Certificate[len];
 
         for (int i = 0; i < len; i++) {
             ByteArrayInputStream bais = null;
             try {
+                byte[] original = certVals[i].getOriginalEncodedForm();
                 if (certfac == null)
-                    certificates[i] = new X509CertImpl(certVals[i]);
+                    certificates[i] = new X509CertImpl(certVals[i], original);
                 else {
-                    byte[] encoded = certVals[i].toByteArray();
-                    bais = new ByteArrayInputStream(encoded);
-                    certificates[i] =
-                        (X509Certificate)certfac.generateCertificate(bais);
+                    bais = new ByteArrayInputStream(original);
+                    certificates[i] = new VerbatimX509Certificate(
+                        (X509Certificate)certfac.generateCertificate(bais),
+                        original);
                     bais.close();
                     bais = null;
                 }
@@ -762,4 +771,196 @@
     public boolean isOldStyle() {
         return this.oldStyle;
     }
+
+    /**
+     * For legacy reasons we need to return exactly the original encoded certificate bytes, instead
+     * of letting the underlying implementation have a shot at re-encoding the data.
+     */
+    private static class VerbatimX509Certificate extends WrappedX509Certificate {
+        private byte[] encodedVerbatim;
+
+        public VerbatimX509Certificate(X509Certificate wrapped, byte[] encodedVerbatim) {
+            super(wrapped);
+            this.encodedVerbatim = encodedVerbatim;
+        }
+
+        @Override
+        public byte[] getEncoded() throws CertificateEncodingException {
+            return encodedVerbatim;
+        }
+    }
+
+    private static class WrappedX509Certificate extends X509Certificate {
+        private final X509Certificate wrapped;
+
+        public WrappedX509Certificate(X509Certificate wrapped) {
+            this.wrapped = wrapped;
+        }
+
+        @Override
+        public Set<String> getCriticalExtensionOIDs() {
+            return wrapped.getCriticalExtensionOIDs();
+        }
+
+        @Override
+        public byte[] getExtensionValue(String oid) {
+            return wrapped.getExtensionValue(oid);
+        }
+
+        @Override
+        public Set<String> getNonCriticalExtensionOIDs() {
+            return wrapped.getNonCriticalExtensionOIDs();
+        }
+
+        @Override
+        public boolean hasUnsupportedCriticalExtension() {
+            return wrapped.hasUnsupportedCriticalExtension();
+        }
+
+        @Override
+        public void checkValidity()
+                throws CertificateExpiredException, CertificateNotYetValidException {
+            wrapped.checkValidity();
+        }
+
+        @Override
+        public void checkValidity(Date date)
+                throws CertificateExpiredException, CertificateNotYetValidException {
+            wrapped.checkValidity(date);
+        }
+
+        @Override
+        public int getVersion() {
+            return wrapped.getVersion();
+        }
+
+        @Override
+        public BigInteger getSerialNumber() {
+            return wrapped.getSerialNumber();
+        }
+
+        @Override
+        public Principal getIssuerDN() {
+            return wrapped.getIssuerDN();
+        }
+
+        @Override
+        public Principal getSubjectDN() {
+            return wrapped.getSubjectDN();
+        }
+
+        @Override
+        public Date getNotBefore() {
+            return wrapped.getNotBefore();
+        }
+
+        @Override
+        public Date getNotAfter() {
+            return wrapped.getNotAfter();
+        }
+
+        @Override
+        public byte[] getTBSCertificate() throws CertificateEncodingException {
+            return wrapped.getTBSCertificate();
+        }
+
+        @Override
+        public byte[] getSignature() {
+            return wrapped.getSignature();
+        }
+
+        @Override
+        public String getSigAlgName() {
+            return wrapped.getSigAlgName();
+        }
+
+        @Override
+        public String getSigAlgOID() {
+            return wrapped.getSigAlgOID();
+        }
+
+        @Override
+        public byte[] getSigAlgParams() {
+            return wrapped.getSigAlgParams();
+        }
+
+        @Override
+        public boolean[] getIssuerUniqueID() {
+            return wrapped.getIssuerUniqueID();
+        }
+
+        @Override
+        public boolean[] getSubjectUniqueID() {
+            return wrapped.getSubjectUniqueID();
+        }
+
+        @Override
+        public boolean[] getKeyUsage() {
+            return wrapped.getKeyUsage();
+        }
+
+        @Override
+        public int getBasicConstraints() {
+            return wrapped.getBasicConstraints();
+        }
+
+        @Override
+        public byte[] getEncoded() throws CertificateEncodingException {
+            return wrapped.getEncoded();
+        }
+
+        @Override
+        public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException,
+                InvalidKeyException, NoSuchProviderException, SignatureException {
+            wrapped.verify(key);
+        }
+
+        @Override
+        public void verify(PublicKey key, String sigProvider)
+                throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
+                NoSuchProviderException, SignatureException {
+            wrapped.verify(key, sigProvider);
+        }
+
+        @Override
+        public String toString() {
+            return wrapped.toString();
+        }
+
+        @Override
+        public PublicKey getPublicKey() {
+            return wrapped.getPublicKey();
+        }
+
+        @Override
+        public List<String> getExtendedKeyUsage() throws CertificateParsingException {
+            return wrapped.getExtendedKeyUsage();
+        }
+
+        @Override
+        public Collection<List<?>> getIssuerAlternativeNames() throws CertificateParsingException {
+            return wrapped.getIssuerAlternativeNames();
+        }
+
+        @Override
+        public X500Principal getIssuerX500Principal() {
+            return wrapped.getIssuerX500Principal();
+        }
+
+        @Override
+        public Collection<List<?>> getSubjectAlternativeNames() throws CertificateParsingException {
+            return wrapped.getSubjectAlternativeNames();
+        }
+
+        @Override
+        public X500Principal getSubjectX500Principal() {
+            return wrapped.getSubjectX500Principal();
+        }
+
+        @Override
+        public void verify(PublicKey key, Provider sigProvider) throws CertificateException,
+                NoSuchAlgorithmException, InvalidKeyException, SignatureException {
+            wrapped.verify(key, sigProvider);
+        }
+    }
 }
diff --git a/ojluni/src/main/java/sun/security/ssl/Alerts.java b/ojluni/src/main/java/sun/security/ssl/Alerts.java
deleted file mode 100755
index 672d9b7..0000000
--- a/ojluni/src/main/java/sun/security/ssl/Alerts.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import javax.net.ssl.*;
-
-/*
- * A simple class to congregate alerts, their definitions, and common
- * support methods.
- */
-
-final class Alerts {
-
-    /*
-     * Alerts are always a fixed two byte format (level/description).
-     */
-
-    // warnings and fatal errors are package private facilities/constants
-
-    // Alert levels (enum AlertLevel)
-    static final byte           alert_warning = 1;
-    static final byte           alert_fatal = 2;
-
-    /*
-     * Alert descriptions (enum AlertDescription)
-     *
-     * We may not use them all in our processing, but if someone
-     * sends us one, we can at least convert it to a string for the
-     * user.
-     */
-    static final byte           alert_close_notify = 0;
-    static final byte           alert_unexpected_message = 10;
-    static final byte           alert_bad_record_mac = 20;
-    static final byte           alert_decryption_failed = 21;
-    static final byte           alert_record_overflow = 22;
-    static final byte           alert_decompression_failure = 30;
-    static final byte           alert_handshake_failure = 40;
-    static final byte           alert_no_certificate = 41;
-    static final byte           alert_bad_certificate = 42;
-    static final byte           alert_unsupported_certificate = 43;
-    static final byte           alert_certificate_revoked = 44;
-    static final byte           alert_certificate_expired = 45;
-    static final byte           alert_certificate_unknown = 46;
-    static final byte           alert_illegal_parameter = 47;
-    static final byte           alert_unknown_ca = 48;
-    static final byte           alert_access_denied = 49;
-    static final byte           alert_decode_error = 50;
-    static final byte           alert_decrypt_error = 51;
-    static final byte           alert_export_restriction = 60;
-    static final byte           alert_protocol_version = 70;
-    static final byte           alert_insufficient_security = 71;
-    static final byte           alert_internal_error = 80;
-    static final byte           alert_user_canceled = 90;
-    static final byte           alert_no_renegotiation = 100;
-
-    // from RFC 3546 (TLS Extensions)
-    static final byte           alert_unsupported_extension = 110;
-    static final byte           alert_certificate_unobtainable = 111;
-    static final byte           alert_unrecognized_name = 112;
-    static final byte           alert_bad_certificate_status_response = 113;
-    static final byte           alert_bad_certificate_hash_value = 114;
-
-    static String alertDescription(byte code) {
-        switch (code) {
-
-        case alert_close_notify:
-            return "close_notify";
-        case alert_unexpected_message:
-            return "unexpected_message";
-        case alert_bad_record_mac:
-            return "bad_record_mac";
-        case alert_decryption_failed:
-            return "decryption_failed";
-        case alert_record_overflow:
-            return "record_overflow";
-        case alert_decompression_failure:
-            return "decompression_failure";
-        case alert_handshake_failure:
-            return "handshake_failure";
-        case alert_no_certificate:
-            return "no_certificate";
-        case alert_bad_certificate:
-            return "bad_certificate";
-        case alert_unsupported_certificate:
-            return "unsupported_certificate";
-        case alert_certificate_revoked:
-            return "certificate_revoked";
-        case alert_certificate_expired:
-            return "certificate_expired";
-        case alert_certificate_unknown:
-            return "certificate_unknown";
-        case alert_illegal_parameter:
-            return "illegal_parameter";
-        case alert_unknown_ca:
-            return "unknown_ca";
-        case alert_access_denied:
-            return "access_denied";
-        case alert_decode_error:
-            return "decode_error";
-        case alert_decrypt_error:
-            return "decrypt_error";
-        case alert_export_restriction:
-            return "export_restriction";
-        case alert_protocol_version:
-            return "protocol_version";
-        case alert_insufficient_security:
-            return "insufficient_security";
-        case alert_internal_error:
-            return "internal_error";
-        case alert_user_canceled:
-            return "user_canceled";
-        case alert_no_renegotiation:
-            return "no_renegotiation";
-        case alert_unsupported_extension:
-            return "unsupported_extension";
-        case alert_certificate_unobtainable:
-            return "certificate_unobtainable";
-        case alert_unrecognized_name:
-            return "unrecognized_name";
-        case alert_bad_certificate_status_response:
-            return "bad_certificate_status_response";
-        case alert_bad_certificate_hash_value:
-            return "bad_certificate_hash_value";
-
-        default:
-            return "<UNKNOWN ALERT: " + (code & 0x0ff) + ">";
-        }
-    }
-
-    static SSLException getSSLException(byte description, String reason) {
-        return getSSLException(description, null, reason);
-    }
-
-    /*
-     * Try to be a little more specific in our choice of
-     * exceptions to throw.
-     */
-    static SSLException getSSLException(byte description, Throwable cause,
-            String reason) {
-
-        SSLException e;
-        // the SSLException classes do not have a no-args constructor
-        // make up a message if there is none
-        if (reason == null) {
-            if (cause != null) {
-                reason = cause.toString();
-            } else {
-                reason = "";
-            }
-        }
-        switch (description) {
-        case alert_handshake_failure:
-        case alert_no_certificate:
-        case alert_bad_certificate:
-        case alert_unsupported_certificate:
-        case alert_certificate_revoked:
-        case alert_certificate_expired:
-        case alert_certificate_unknown:
-        case alert_unknown_ca:
-        case alert_access_denied:
-        case alert_decrypt_error:
-        case alert_export_restriction:
-        case alert_insufficient_security:
-        case alert_unsupported_extension:
-        case alert_certificate_unobtainable:
-        case alert_unrecognized_name:
-        case alert_bad_certificate_status_response:
-        case alert_bad_certificate_hash_value:
-            e = new SSLHandshakeException(reason);
-            break;
-
-        case alert_close_notify:
-        case alert_unexpected_message:
-        case alert_bad_record_mac:
-        case alert_decryption_failed:
-        case alert_record_overflow:
-        case alert_decompression_failure:
-        case alert_illegal_parameter:
-        case alert_decode_error:
-        case alert_protocol_version:
-        case alert_internal_error:
-        case alert_user_canceled:
-        case alert_no_renegotiation:
-        default:
-            e = new SSLException(reason);
-            break;
-        }
-
-        if (cause != null) {
-            e.initCause(cause);
-        }
-        return e;
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/AppInputStream.java b/ojluni/src/main/java/sun/security/ssl/AppInputStream.java
deleted file mode 100755
index 6c47978..0000000
--- a/ojluni/src/main/java/sun/security/ssl/AppInputStream.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.*;
-
-/**
- * InputStream for application data as returned by SSLSocket.getInputStream().
- * It uses an InputRecord as internal buffer that is refilled on demand
- * whenever it runs out of data.
- *
- * @author David Brownell
- */
-class AppInputStream extends InputStream {
-
-    // static dummy array we use to implement skip()
-    private final static byte[] SKIP_ARRAY = new byte[1024];
-
-    private SSLSocketImpl c;
-    InputRecord r;
-
-    // One element array used to implement the single byte read() method
-    private final byte[] oneByte = new byte[1];
-
-    AppInputStream(SSLSocketImpl conn) {
-        r = new InputRecord();
-        c = conn;
-    }
-
-    /**
-     * Return the minimum number of bytes that can be read without blocking.
-     * Currently not synchronized.
-     */
-    public int available() throws IOException {
-        if (c.checkEOF() || (r.isAppDataValid() == false)) {
-            return 0;
-        }
-        return r.available();
-    }
-
-    /**
-     * Read a single byte, returning -1 on non-fault EOF status.
-     */
-    public synchronized int read() throws IOException {
-        int n = read(oneByte, 0, 1);
-        if (n <= 0) { // EOF
-            return -1;
-        }
-        return oneByte[0] & 0xff;
-    }
-
-    /**
-     * Read up to "len" bytes into this buffer, starting at "off".
-     * If the layer above needs more data, it asks for more, so we
-     * are responsible only for blocking to fill at most one buffer,
-     * and returning "-1" on non-fault EOF status.
-     */
-    public synchronized int read(byte b[], int off, int len)
-            throws IOException {
-        if (b == null) {
-            throw new NullPointerException();
-        } else if (off < 0 || len < 0 || len > b.length - off) {
-            throw new IndexOutOfBoundsException();
-        } else if (len == 0) {
-            return 0;
-        }
-
-        if (c.checkEOF()) {
-            return -1;
-        }
-        try {
-            /*
-             * Read data if needed ... notice that the connection guarantees
-             * that handshake, alert, and change cipher spec data streams are
-             * handled as they arrive, so we never see them here.
-             */
-            while (r.available() == 0) {
-                c.readDataRecord(r);
-                if (c.checkEOF()) {
-                    return -1;
-                }
-            }
-
-            int howmany = Math.min(len, r.available());
-            howmany = r.read(b, off, howmany);
-            return howmany;
-        } catch (Exception e) {
-            // shutdown and rethrow (wrapped) exception as appropriate
-            c.handleException(e);
-            // dummy for compiler
-            return -1;
-        }
-    }
-
-
-    /**
-     * Skip n bytes. This implementation is somewhat less efficient
-     * than possible, but not badly so (redundant copy). We reuse
-     * the read() code to keep things simpler. Note that SKIP_ARRAY
-     * is static and may garbled by concurrent use, but we are not interested
-     * in the data anyway.
-     */
-    public synchronized long skip(long n) throws IOException {
-        long skipped = 0;
-        while (n > 0) {
-            int len = (int)Math.min(n, SKIP_ARRAY.length);
-            int r = read(SKIP_ARRAY, 0, len);
-            if (r <= 0) {
-                break;
-            }
-            n -= r;
-            skipped += r;
-        }
-        return skipped;
-    }
-
-    /*
-     * Socket close is already synchronized, no need to block here.
-     */
-    public void close() throws IOException {
-        c.close();
-    }
-
-    // inherit default mark/reset behavior (throw Exceptions) from InputStream
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/AppOutputStream.java b/ojluni/src/main/java/sun/security/ssl/AppOutputStream.java
deleted file mode 100755
index 5082bec..0000000
--- a/ojluni/src/main/java/sun/security/ssl/AppOutputStream.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.OutputStream;
-import java.io.IOException;
-
-/*
- * Output stream for application data. This is the kind of stream
- * that's handed out via SSLSocket.getOutputStream(). It's all the application
- * ever sees.
- *
- * Once the initial handshake has completed, application data may be
- * interleaved with handshake data. That is handled internally and remains
- * transparent to the application.
- *
- * @author  David Brownell
- */
-class AppOutputStream extends OutputStream {
-
-    private SSLSocketImpl c;
-    OutputRecord r;
-
-    // One element array used to implement the write(byte) method
-    private final byte[] oneByte = new byte[1];
-
-    AppOutputStream(SSLSocketImpl conn) {
-        r = new OutputRecord(Record.ct_application_data);
-        c = conn;
-    }
-
-    /**
-     * Write the data out, NOW.
-     */
-    synchronized public void write(byte b[], int off, int len)
-            throws IOException {
-        if (b == null) {
-            throw new NullPointerException();
-        } else if (off < 0 || len < 0 || len > b.length - off) {
-            throw new IndexOutOfBoundsException();
-        } else if (len == 0) {
-            return;
-        }
-
-        // check if the Socket is invalid (error or closed)
-        c.checkWrite();
-
-        /*
-         * By default, we counter chosen plaintext issues on CBC mode
-         * ciphersuites in SSLv3/TLS1.0 by sending one byte of application
-         * data in the first record of every payload, and the rest in
-         * subsequent record(s). Note that the issues have been solved in
-         * TLS 1.1 or later.
-         *
-         * It is not necessary to split the very first application record of
-         * a freshly negotiated TLS session, as there is no previous
-         * application data to guess.  To improve compatibility, we will not
-         * split such records.
-         *
-         * This avoids issues in the outbound direction.  For a full fix,
-         * the peer must have similar protections.
-         */
-        boolean isFirstRecordOfThePayload = true;
-
-        // Always flush at the end of each application level record.
-        // This lets application synchronize read and write streams
-        // however they like; if we buffered here, they couldn't.
-        try {
-            do {
-                boolean holdRecord = false;
-                int howmuch;
-                if (isFirstRecordOfThePayload && c.needToSplitPayload()) {
-                    howmuch = Math.min(0x01, r.availableDataBytes());
-                    /*
-                     * Nagle's algorithm (TCP_NODELAY) was coming into
-                     * play here when writing short (split) packets.
-                     * Signal to the OutputRecord code to internally
-                     * buffer this small packet until the next outbound
-                     * packet (of any type) is written.
-                     */
-                    if ((len != 1) && (howmuch == 1)) {
-                        holdRecord = true;
-                    }
-                } else {
-                    howmuch = Math.min(len, r.availableDataBytes());
-                }
-
-                if (isFirstRecordOfThePayload && howmuch != 0) {
-                    isFirstRecordOfThePayload = false;
-                }
-
-                // NOTE: *must* call c.writeRecord() even for howmuch == 0
-                if (howmuch > 0) {
-                    r.write(b, off, howmuch);
-                    off += howmuch;
-                    len -= howmuch;
-                }
-                c.writeRecord(r, holdRecord);
-                c.checkWrite();
-            } while (len > 0);
-        } catch (Exception e) {
-            // shutdown and rethrow (wrapped) exception as appropriate
-            c.handleException(e);
-        }
-    }
-
-    /**
-     * Write one byte now.
-     */
-    synchronized public void write(int i) throws IOException {
-        oneByte[0] = (byte)i;
-        write(oneByte, 0, 1);
-    }
-
-    /*
-     * Socket close is already synchronized, no need to block here.
-     */
-    public void close() throws IOException {
-        c.close();
-    }
-
-    // inherit no-op flush()
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/BaseSSLSocketImpl.java b/ojluni/src/main/java/sun/security/ssl/BaseSSLSocketImpl.java
deleted file mode 100755
index ef7503b..0000000
--- a/ojluni/src/main/java/sun/security/ssl/BaseSSLSocketImpl.java
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.nio.channels.SocketChannel;
-import java.net.*;
-
-import javax.net.ssl.*;
-
-/**
- * Abstract base class for SSLSocketImpl. Its purpose is to house code with
- * no SSL related logic (or no logic at all). This makes SSLSocketImpl shorter
- * and easier to read. It contains a few constants and static methods plus
- * overridden java.net.Socket methods.
- *
- * Methods are defined final to ensure that they are not accidentally
- * overridden in SSLSocketImpl.
- *
- * @see javax.net.ssl.SSLSocket
- * @see SSLSocketImpl
- *
- */
-abstract class BaseSSLSocketImpl extends SSLSocket {
-
-    /*
-     * Normally "self" is "this" ... but not when this connection is
-     * layered over a preexisting socket.  If we're using an existing
-     * socket, we delegate some actions to it.  Else, we delegate
-     * instead to "super".  This is important to ensure that we don't
-     * recurse infinitely ... e.g. close() calling itself, or doing
-     * I/O in terms of our own streams.
-     */
-    final Socket self;
-
-    BaseSSLSocketImpl() {
-        super();
-        this.self = this;
-    }
-
-    BaseSSLSocketImpl(Socket socket) {
-        super();
-        this.self = socket;
-    }
-
-    //
-    // CONSTANTS AND STATIC METHODS
-    //
-
-    /**
-     * TLS requires that a close_notify warning alert is sent before the
-     * connection is closed in order to avoid truncation attacks. Some
-     * implementations (MS IIS and others) don't do that. The property
-     * below controls whether we accept that or treat it as an error.
-     *
-     * The default is "false", i.e. tolerate the broken behavior.
-     */
-    private final static String PROP_NAME =
-                                "com.sun.net.ssl.requireCloseNotify";
-
-    final static boolean requireCloseNotify =
-                                Debug.getBooleanProperty(PROP_NAME, false);
-
-    //
-    // MISC SOCKET METHODS
-    //
-
-    /**
-     * Returns the unique {@link java.nio.SocketChannel SocketChannel} object
-     * associated with this socket, if any.
-     * @see java.net.Socket#getChannel
-     */
-    public final SocketChannel getChannel() {
-        if (self == this) {
-            return super.getChannel();
-        } else {
-            return self.getChannel();
-        }
-    }
-
-    /**
-     * Binds the address to the socket.
-     * @see java.net.Socket#bind
-     */
-    public void bind(SocketAddress bindpoint) throws IOException {
-        /*
-         * Bind to this socket
-         */
-        if (self == this) {
-            super.bind(bindpoint);
-        } else {
-            // If we're binding on a layered socket...
-            throw new IOException(
-                "Underlying socket should already be connected");
-        }
-    }
-
-    /**
-     * Returns the address of the endpoint this socket is connected to
-     * @see java.net.Socket#getLocalSocketAddress
-     */
-    public SocketAddress getLocalSocketAddress() {
-        if (self == this) {
-            return super.getLocalSocketAddress();
-        } else {
-            return self.getLocalSocketAddress();
-        }
-    }
-
-    /**
-     * Returns the address of the endpoint this socket is connected to
-     * @see java.net.Socket#getRemoteSocketAddress
-     */
-    public SocketAddress getRemoteSocketAddress() {
-        if (self == this) {
-            return super.getRemoteSocketAddress();
-        } else {
-            return self.getRemoteSocketAddress();
-        }
-    }
-
-    /**
-     * Connects this socket to the server.
-     *
-     * This method is either called on an unconnected SSLSocketImpl by the
-     * application, or it is called in the constructor of a regular
-     * SSLSocketImpl. If we are layering on top on another socket, then
-     * this method should not be called, because we assume that the
-     * underlying socket is already connected by the time it is passed to
-     * us.
-     *
-     * @param   endpoint the <code>SocketAddress</code>
-     * @throws  IOException if an error occurs during the connection
-     */
-    public final void connect(SocketAddress endpoint) throws IOException {
-        connect(endpoint, 0);
-    }
-
-    /**
-     * Returns the connection state of the socket.
-     * @see java.net.Socket#isConnected
-     */
-    public final boolean isConnected() {
-        if (self == this) {
-            return super.isConnected();
-        } else {
-            return self.isConnected();
-        }
-    }
-
-    /**
-     * Returns the binding state of the socket.
-     * @see java.net.Socket#isBound
-     */
-    public final boolean isBound() {
-        if (self == this) {
-            return super.isBound();
-        } else {
-            return self.isBound();
-        }
-    }
-
-    //
-    // CLOSE RELATED METHODS
-    //
-
-    /**
-     * The semantics of shutdownInput is not supported in TLS 1.0
-     * spec. Thus when the method is called on an SSL socket, an
-     * UnsupportedOperationException will be thrown.
-     *
-     * @throws UnsupportedOperationException
-     */
-    public final void shutdownInput() throws IOException {
-        throw new UnsupportedOperationException("The method shutdownInput()" +
-                   " is not supported in SSLSocket");
-    }
-
-    /**
-     * The semantics of shutdownOutput is not supported in TLS 1.0
-     * spec. Thus when the method is called on an SSL socket, an
-     * UnsupportedOperationException will be thrown.
-     *
-     * @throws UnsupportedOperationException
-     */
-    public final void shutdownOutput() throws IOException {
-        throw new UnsupportedOperationException("The method shutdownOutput()" +
-                   " is not supported in SSLSocket");
-
-    }
-
-    /**
-     * Returns the input state of the socket
-     * @see java.net.Socket#isInputShutdown
-     */
-    public final boolean isInputShutdown() {
-        if (self == this) {
-            return super.isInputShutdown();
-        } else {
-            return self.isInputShutdown();
-        }
-    }
-
-    /**
-     * Returns the output state of the socket
-     * @see java.net.Socket#isOutputShutdown
-     */
-    public final boolean isOutputShutdown() {
-        if (self == this) {
-            return super.isOutputShutdown();
-        } else {
-            return self.isOutputShutdown();
-        }
-    }
-
-    /**
-     * Ensures that the SSL connection is closed down as cleanly
-     * as possible, in case the application forgets to do so.
-     * This allows SSL connections to be implicitly reclaimed,
-     * rather than forcing them to be explicitly reclaimed at
-     * the penalty of prematurly killing SSL sessions.
-     */
-    protected final void finalize() throws Throwable {
-        try {
-            close();
-        } catch (IOException e1) {
-            try {
-                if (self == this) {
-                    super.close();
-                }
-            } catch (IOException e2) {
-                // ignore
-            }
-        } finally {
-            // We called close on the underlying socket above to
-            // make doubly sure all resources got released.  We
-            // don't finalize self in the case of overlain sockets,
-            // that's a different object which the GC will finalize
-            // separately.
-
-            super.finalize();
-        }
-    }
-
-    //
-    // GET ADDRESS METHODS
-    //
-
-    /**
-     * Returns the address of the remote peer for this connection.
-     */
-    public final InetAddress getInetAddress() {
-        if (self == this) {
-            return super.getInetAddress();
-        } else {
-            return self.getInetAddress();
-        }
-    }
-
-    /**
-     * Gets the local address to which the socket is bound.
-     *
-     * @return the local address to which the socket is bound.
-     * @since   JDK1.1
-     */
-    public final InetAddress getLocalAddress() {
-        if (self == this) {
-            return super.getLocalAddress();
-        } else {
-            return self.getLocalAddress();
-        }
-    }
-
-    /**
-     * Returns the number of the remote port that this connection uses.
-     */
-    public final int getPort() {
-        if (self == this) {
-            return super.getPort();
-        } else {
-            return self.getPort();
-        }
-    }
-
-    /**
-     * Returns the number of the local port that this connection uses.
-     */
-    public final int getLocalPort() {
-        if (self == this) {
-            return super.getLocalPort();
-        } else {
-            return self.getLocalPort();
-        }
-    }
-
-    //
-    // SOCKET OPTION METHODS
-    //
-
-    /**
-     * Enables or disables the Nagle optimization.
-     * @see java.net.Socket#setTcpNoDelay
-     */
-    public final void setTcpNoDelay(boolean value) throws SocketException {
-        if (self == this) {
-            super.setTcpNoDelay(value);
-        } else {
-            self.setTcpNoDelay(value);
-        }
-    }
-
-    /**
-     * Returns true if the Nagle optimization is disabled.  This
-     * relates to low-level buffering of TCP traffic, delaying the
-     * traffic to promote better throughput.
-     *
-     * @see java.net.Socket#getTcpNoDelay
-     */
-    public final boolean getTcpNoDelay() throws SocketException {
-        if (self == this) {
-            return super.getTcpNoDelay();
-        } else {
-            return self.getTcpNoDelay();
-        }
-    }
-
-    /**
-     * Assigns the socket's linger timeout.
-     * @see java.net.Socket#setSoLinger
-     */
-    public final void setSoLinger(boolean flag, int linger)
-            throws SocketException {
-        if (self == this) {
-            super.setSoLinger(flag, linger);
-        } else {
-            self.setSoLinger(flag, linger);
-        }
-    }
-
-    /**
-     * Returns the socket's linger timeout.
-     * @see java.net.Socket#getSoLinger
-     */
-    public final int getSoLinger() throws SocketException {
-        if (self == this) {
-            return super.getSoLinger();
-        } else {
-            return self.getSoLinger();
-        }
-    }
-
-    /**
-     * Send one byte of urgent data on the socket.
-     * @see java.net.Socket#sendUrgentData
-     * At this point, there seems to be no specific requirement to support
-     * this for an SSLSocket. An implementation can be provided if a need
-     * arises in future.
-     */
-    public final void sendUrgentData(int data) throws SocketException {
-        throw new SocketException("This method is not supported "
-                        + "by SSLSockets");
-    }
-
-    /**
-     * Enable/disable OOBINLINE (receipt of TCP urgent data) By default, this
-     * option is disabled and TCP urgent data received on a socket is silently
-     * discarded.
-     * @see java.net.Socket#setOOBInline
-     * Setting OOBInline does not have any effect on SSLSocket,
-     * since currently we don't support sending urgent data.
-     */
-    public final void setOOBInline(boolean on) throws SocketException {
-        throw new SocketException("This method is ineffective, since"
-                + " sending urgent data is not supported by SSLSockets");
-    }
-
-    /**
-     * Tests if OOBINLINE is enabled.
-     * @see java.net.Socket#getOOBInline
-     */
-    public final boolean getOOBInline() throws SocketException {
-        throw new SocketException("This method is ineffective, since"
-                + " sending urgent data is not supported by SSLSockets");
-    }
-
-    /**
-     * Returns the socket timeout.
-     * @see java.net.Socket#getSoTimeout
-     */
-    public final int getSoTimeout() throws SocketException {
-        if (self == this) {
-            return super.getSoTimeout();
-        } else {
-            return self.getSoTimeout();
-        }
-    }
-
-    public final void setSendBufferSize(int size) throws SocketException {
-        if (self == this) {
-            super.setSendBufferSize(size);
-        } else {
-            self.setSendBufferSize(size);
-        }
-    }
-
-    public final int getSendBufferSize() throws SocketException {
-        if (self == this) {
-            return super.getSendBufferSize();
-        } else {
-            return self.getSendBufferSize();
-        }
-    }
-
-    public final void setReceiveBufferSize(int size) throws SocketException {
-        if (self == this) {
-            super.setReceiveBufferSize(size);
-        } else {
-            self.setReceiveBufferSize(size);
-        }
-    }
-
-    public final int getReceiveBufferSize() throws SocketException {
-        if (self == this) {
-            return super.getReceiveBufferSize();
-        } else {
-            return self.getReceiveBufferSize();
-        }
-    }
-
-    /**
-     * Enable/disable SO_KEEPALIVE.
-     * @see java.net.Socket#setKeepAlive
-     */
-    public final void setKeepAlive(boolean on) throws SocketException {
-        if (self == this) {
-            super.setKeepAlive(on);
-        } else {
-            self.setKeepAlive(on);
-        }
-    }
-
-    /**
-     * Tests if SO_KEEPALIVE is enabled.
-     * @see java.net.Socket#getKeepAlive
-     */
-    public final boolean getKeepAlive() throws SocketException {
-        if (self == this) {
-            return super.getKeepAlive();
-        } else {
-            return self.getKeepAlive();
-        }
-    }
-
-    /**
-     * Sets traffic class or type-of-service octet in the IP header for
-     * packets sent from this Socket.
-     * @see java.net.Socket#setTrafficClass
-     */
-    public final void setTrafficClass(int tc) throws SocketException {
-        if (self == this) {
-            super.setTrafficClass(tc);
-        } else {
-            self.setTrafficClass(tc);
-        }
-    }
-
-    /**
-     * Gets traffic class or type-of-service in the IP header for packets
-     * sent from this Socket.
-     * @see java.net.Socket#getTrafficClass
-     */
-    public final int getTrafficClass() throws SocketException {
-        if (self == this) {
-            return super.getTrafficClass();
-        } else {
-            return self.getTrafficClass();
-        }
-    }
-
-    /**
-     * Enable/disable SO_REUSEADDR.
-     * @see java.net.Socket#setReuseAddress
-     */
-    public final void setReuseAddress(boolean on) throws SocketException {
-        if (self == this) {
-            super.setReuseAddress(on);
-        } else {
-            self.setReuseAddress(on);
-        }
-    }
-
-    /**
-     * Tests if SO_REUSEADDR is enabled.
-     * @see java.net.Socket#getReuseAddress
-     */
-    public final boolean getReuseAddress() throws SocketException {
-        if (self == this) {
-            return super.getReuseAddress();
-        } else {
-            return self.getReuseAddress();
-        }
-    }
-
-    /**
-     * Sets performance preferences for this socket.
-     *
-     * @see java.net.Socket#setPerformancePreferences(int, int, int)
-     */
-    public void setPerformancePreferences(int connectionTime,
-            int latency, int bandwidth) {
-        if (self == this) {
-            super.setPerformancePreferences(
-                connectionTime, latency, bandwidth);
-        } else {
-            self.setPerformancePreferences(
-                connectionTime, latency, bandwidth);
-        }
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/ByteBufferInputStream.java b/ojluni/src/main/java/sun/security/ssl/ByteBufferInputStream.java
deleted file mode 100755
index 7191621..0000000
--- a/ojluni/src/main/java/sun/security/ssl/ByteBufferInputStream.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.nio.*;
-
-/**
- * A simple InputStream which uses ByteBuffers as it's backing store.
- * <P>
- * The only IOException should come if the InputStream has been closed.
- * All other IOException should not occur because all the data is local.
- * Data reads on an exhausted ByteBuffer returns a -1.
- *
- * @author  Brad Wetmore
- */
-class ByteBufferInputStream extends InputStream {
-
-    ByteBuffer bb;
-
-    ByteBufferInputStream(ByteBuffer bb) {
-        this.bb = bb;
-    }
-
-    /**
-     * Returns a byte from the ByteBuffer.
-     *
-     * Increments position().
-     */
-    public int read() throws IOException {
-
-        if (bb == null) {
-            throw new IOException("read on a closed InputStream");
-        }
-
-        if (bb.remaining() == 0) {
-            return -1;
-        }
-        return bb.get();
-    }
-
-    /**
-     * Returns a byte array from the ByteBuffer.
-     *
-     * Increments position().
-     */
-    public int read(byte b[]) throws IOException {
-
-        if (bb == null) {
-            throw new IOException("read on a closed InputStream");
-        }
-
-        return read(b, 0, b.length);
-    }
-
-    /**
-     * Returns a byte array from the ByteBuffer.
-     *
-     * Increments position().
-     */
-    public int read(byte b[], int off, int len) throws IOException {
-
-        if (bb == null) {
-            throw new IOException("read on a closed InputStream");
-        }
-
-        if (b == null) {
-            throw new NullPointerException();
-        } else if (off < 0 || len < 0 || len > b.length - off) {
-            throw new IndexOutOfBoundsException();
-        } else if (len == 0) {
-            return 0;
-        }
-
-        int length = Math.min(bb.remaining(), len);
-        if (length == 0) {
-            return -1;
-        }
-
-        bb.get(b, off, length);
-        return length;
-    }
-
-    /**
-     * Skips over and discards <code>n</code> bytes of data from this input
-     * stream.
-     */
-    public long skip(long n) throws IOException {
-
-        if (bb == null) {
-            throw new IOException("skip on a closed InputStream");
-        }
-
-        if (n <= 0) {
-            return 0;
-        }
-
-        /*
-         * ByteBuffers have at most an int, so lose the upper bits.
-         * The contract allows this.
-         */
-        int nInt = (int) n;
-        int skip = Math.min(bb.remaining(), nInt);
-
-        bb.position(bb.position() + skip);
-
-        return nInt;
-    }
-
-    /**
-     * Returns the number of bytes that can be read (or skipped over)
-     * from this input stream without blocking by the next caller of a
-     * method for this input stream.
-     */
-    public int available() throws IOException {
-
-        if (bb == null) {
-            throw new IOException("available on a closed InputStream");
-        }
-
-        return bb.remaining();
-    }
-
-    /**
-     * Closes this input stream and releases any system resources associated
-     * with the stream.
-     *
-     * @exception  IOException  if an I/O error occurs.
-     */
-    public void close() throws IOException {
-        bb = null;
-    }
-
-    /**
-     * Marks the current position in this input stream.
-     */
-    public synchronized void mark(int readlimit) {}
-
-    /**
-     * Repositions this stream to the position at the time the
-     * <code>mark</code> method was last called on this input stream.
-     */
-    public synchronized void reset() throws IOException {
-        throw new IOException("mark/reset not supported");
-    }
-
-    /**
-     * Tests if this input stream supports the <code>mark</code> and
-     * <code>reset</code> methods.
-     */
-    public boolean markSupported() {
-        return false;
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/CipherBox.java b/ojluni/src/main/java/sun/security/ssl/CipherBox.java
deleted file mode 100755
index 4dfbadd..0000000
--- a/ojluni/src/main/java/sun/security/ssl/CipherBox.java
+++ /dev/null
@@ -1,824 +0,0 @@
-/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.util.Hashtable;
-
-import java.security.*;
-import javax.crypto.*;
-import javax.crypto.spec.SecretKeySpec;
-import javax.crypto.spec.IvParameterSpec;
-
-import java.nio.*;
-
-import sun.security.ssl.CipherSuite.*;
-import static sun.security.ssl.CipherSuite.*;
-
-import sun.misc.HexDumpEncoder;
-
-
-/**
- * This class handles bulk data enciphering/deciphering for each SSLv3
- * message.  This provides data confidentiality.  Stream ciphers (such
- * as RC4) don't need to do padding; block ciphers (e.g. DES) need it.
- *
- * Individual instances are obtained by calling the static method
- * newCipherBox(), which should only be invoked by BulkCipher.newCipher().
- *
- * In RFC 2246, with bock ciphers in CBC mode, the Initialization
- * Vector (IV) for the first record is generated with the other keys
- * and secrets when the security parameters are set.  The IV for
- * subsequent records is the last ciphertext block from the previous
- * record.
- *
- * In RFC 4346, the implicit Initialization Vector (IV) is replaced
- * with an explicit IV to protect against CBC attacks.  RFC 4346
- * recommends two algorithms used to generated the per-record IV.
- * The implementation uses the algorithm (2)(b), as described at
- * section 6.2.3.2 of RFC 4346.
- *
- * The usage of IV in CBC block cipher can be illustrated in
- * the following diagrams.
- *
- *   (random)
- *        R         P1                    IV        C1
- *        |          |                     |         |
- *  SIV---+    |-----+    |-...            |-----    |------
- *        |    |     |    |                |    |    |     |
- *     +----+  |  +----+  |             +----+  |  +----+  |
- *     | Ek |  |  + Ek +  |             | Dk |  |  | Dk |  |
- *     +----+  |  +----+  |             +----+  |  +----+  |
- *        |    |     |    |                |    |    |     |
- *        |----|     |----|           SIV--+    |----|     |-...
- *        |          |                     |       |
- *       IV         C1                     R      P1
- *                                     (discard)
- *
- *       CBC Encryption                    CBC Decryption
- *
- * NOTE that any ciphering involved in key exchange (e.g. with RSA) is
- * handled separately.
- *
- * @author David Brownell
- * @author Andreas Sterbenz
- */
-final class CipherBox {
-
-    // A CipherBox that implements the identity operation
-    final static CipherBox NULL = new CipherBox();
-
-    /* Class and subclass dynamic debugging support */
-    private static final Debug debug = Debug.getInstance("ssl");
-
-    // the protocol version this cipher conforms to
-    private final ProtocolVersion protocolVersion;
-
-    // cipher object
-    private final Cipher cipher;
-
-    /**
-     * Cipher blocksize, 0 for stream ciphers
-     */
-    private int blockSize;
-
-    /**
-     * secure random
-     */
-    private SecureRandom random;
-
-    /**
-     * Is the cipher of CBC mode?
-     */
-    private final boolean isCBCMode;
-
-    /**
-     * Fixed masks of various block size, as the initial decryption IVs
-     * for TLS 1.1 or later.
-     *
-     * For performance, we do not use random IVs. As the initial decryption
-     * IVs will be discarded by TLS decryption processes, so the fixed masks
-     * do not hurt cryptographic strength.
-     */
-    private static Hashtable<Integer, IvParameterSpec> masks;
-
-    /**
-     * NULL cipherbox. Identity operation, no encryption.
-     */
-    private CipherBox() {
-        this.protocolVersion = ProtocolVersion.DEFAULT;
-        this.cipher = null;
-        this.isCBCMode = false;
-    }
-
-    /**
-     * Construct a new CipherBox using the cipher transformation.
-     *
-     * @exception NoSuchAlgorithmException if no appropriate JCE Cipher
-     * implementation could be found.
-     */
-    private CipherBox(ProtocolVersion protocolVersion, BulkCipher bulkCipher,
-            SecretKey key, IvParameterSpec iv, SecureRandom random,
-            boolean encrypt) throws NoSuchAlgorithmException {
-        try {
-            this.protocolVersion = protocolVersion;
-            this.cipher = JsseJce.getCipher(bulkCipher.transformation);
-            int mode = encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE;
-
-            if (random == null) {
-                random = JsseJce.getSecureRandom();
-            }
-            this.random = random;
-            this.isCBCMode = bulkCipher.isCBCMode;
-
-            /*
-             * RFC 4346 recommends two algorithms used to generated the
-             * per-record IV. The implementation uses the algorithm (2)(b),
-             * as described at section 6.2.3.2 of RFC 4346.
-             *
-             * As we don't care about the initial IV value for TLS 1.1 or
-             * later, so if the "iv" parameter is null, we use the default
-             * value generated by Cipher.init() for encryption, and a fixed
-             * mask for decryption.
-             */
-            if (iv == null && bulkCipher.ivSize != 0 &&
-                    mode == Cipher.DECRYPT_MODE &&
-                    protocolVersion.v >= ProtocolVersion.TLS11.v) {
-                iv = getFixedMask(bulkCipher.ivSize);
-            }
-
-            cipher.init(mode, key, iv, random);
-
-            // Do not call getBlockSize until after init()
-            // otherwise we would disrupt JCE delayed provider selection
-            blockSize = cipher.getBlockSize();
-            // some providers implement getBlockSize() incorrectly
-            if (blockSize == 1) {
-                blockSize = 0;
-            }
-        } catch (NoSuchAlgorithmException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new NoSuchAlgorithmException
-                    ("Could not create cipher " + bulkCipher, e);
-        } catch (ExceptionInInitializerError e) {
-            throw new NoSuchAlgorithmException
-                    ("Could not create cipher " + bulkCipher, e);
-        }
-    }
-
-    /*
-     * Factory method to obtain a new CipherBox object.
-     */
-    static CipherBox newCipherBox(ProtocolVersion version, BulkCipher cipher,
-            SecretKey key, IvParameterSpec iv, SecureRandom random,
-            boolean encrypt) throws NoSuchAlgorithmException {
-        if (cipher.allowed == false) {
-            throw new NoSuchAlgorithmException("Unsupported cipher " + cipher);
-        }
-
-        if (cipher == B_NULL) {
-            return NULL;
-        } else {
-            return new CipherBox(version, cipher, key, iv, random, encrypt);
-        }
-    }
-
-    /*
-     * Get a fixed mask, as the initial decryption IVs for TLS 1.1 or later.
-     */
-    private static IvParameterSpec getFixedMask(int ivSize) {
-        if (masks == null) {
-            masks = new Hashtable<Integer, IvParameterSpec>(5);
-        }
-
-        IvParameterSpec iv = masks.get(ivSize);
-        if (iv == null) {
-            iv = new IvParameterSpec(new byte[ivSize]);
-            masks.put(ivSize, iv);
-        }
-
-        return iv;
-    }
-
-    /*
-     * Encrypts a block of data, returning the size of the
-     * resulting block.
-     */
-    int encrypt(byte[] buf, int offset, int len) {
-        if (cipher == null) {
-            return len;
-        }
-
-        try {
-            if (blockSize != 0) {
-                // TLSv1.1 needs a IV block
-                if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
-                    // generate a random number
-                    byte[] prefix = new byte[blockSize];
-                    random.nextBytes(prefix);
-
-                    // move forward the plaintext
-                    System.arraycopy(buf, offset,
-                                     buf, offset + prefix.length, len);
-
-                    // prefix the plaintext
-                    System.arraycopy(prefix, 0,
-                                     buf, offset, prefix.length);
-
-                    len += prefix.length;
-                }
-
-                len = addPadding(buf, offset, len, blockSize);
-            }
-            if (debug != null && Debug.isOn("plaintext")) {
-                try {
-                    HexDumpEncoder hd = new HexDumpEncoder();
-
-                    System.out.println(
-                        "Padded plaintext before ENCRYPTION:  len = "
-                        + len);
-                    hd.encodeBuffer(
-                        new ByteArrayInputStream(buf, offset, len),
-                        System.out);
-                } catch (IOException e) { }
-            }
-            int newLen = cipher.update(buf, offset, len, buf, offset);
-            if (newLen != len) {
-                // catch BouncyCastle buffering error
-                throw new RuntimeException("Cipher buffering error " +
-                    "in JCE provider " + cipher.getProvider().getName());
-            }
-            return newLen;
-        } catch (ShortBufferException e) {
-            throw new ArrayIndexOutOfBoundsException(e.toString());
-        }
-    }
-
-    /*
-     * Encrypts a ByteBuffer block of data, returning the size of the
-     * resulting block.
-     *
-     * The byte buffers position and limit initially define the amount
-     * to encrypt.  On return, the position and limit are
-     * set to last position padded/encrypted.  The limit may have changed
-     * because of the added padding bytes.
-     */
-    int encrypt(ByteBuffer bb) {
-
-        int len = bb.remaining();
-
-        if (cipher == null) {
-            bb.position(bb.limit());
-            return len;
-        }
-
-        try {
-            int pos = bb.position();
-
-            if (blockSize != 0) {
-                // TLSv1.1 needs a IV block
-                if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
-                    // generate a random number
-                    byte[] prefix = new byte[blockSize];
-                    random.nextBytes(prefix);
-
-                    // move forward the plaintext
-                    byte[] buf = null;
-                    int limit = bb.limit();
-                    if (bb.hasArray()) {
-                        int arrayOffset = bb.arrayOffset();
-                        buf = bb.array();
-                        System.arraycopy(buf, arrayOffset + pos,
-                            buf, arrayOffset + pos + prefix.length,
-                            limit - pos);
-                        bb.limit(limit + prefix.length);
-                    } else {
-                        buf = new byte[limit - pos];
-                        bb.get(buf, 0, limit - pos);
-                        bb.position(pos + prefix.length);
-                        bb.limit(limit + prefix.length);
-                        bb.put(buf);
-                    }
-                    bb.position(pos);
-
-                    // prefix the plaintext
-                    bb.put(prefix);
-                    bb.position(pos);
-                }
-
-                // addPadding adjusts pos/limit
-                len = addPadding(bb, blockSize);
-                bb.position(pos);
-            }
-            if (debug != null && Debug.isOn("plaintext")) {
-                try {
-                    HexDumpEncoder hd = new HexDumpEncoder();
-
-                    System.out.println(
-                        "Padded plaintext before ENCRYPTION:  len = "
-                        + len);
-                    hd.encodeBuffer(bb, System.out);
-
-                } catch (IOException e) { }
-                /*
-                 * reset back to beginning
-                 */
-                bb.position(pos);
-            }
-
-            /*
-             * Encrypt "in-place".  This does not add its own padding.
-             */
-            ByteBuffer dup = bb.duplicate();
-            int newLen = cipher.update(dup, bb);
-
-            if (bb.position() != dup.position()) {
-                throw new RuntimeException("bytebuffer padding error");
-            }
-
-            if (newLen != len) {
-                // catch BouncyCastle buffering error
-                throw new RuntimeException("Cipher buffering error " +
-                    "in JCE provider " + cipher.getProvider().getName());
-            }
-            return newLen;
-        } catch (ShortBufferException e) {
-            RuntimeException exc = new RuntimeException(e.toString());
-            exc.initCause(e);
-            throw exc;
-        }
-    }
-
-
-    /*
-     * Decrypts a block of data, returning the size of the
-     * resulting block if padding was required.
-     *
-     * For SSLv3 and TLSv1.0, with block ciphers in CBC mode the
-     * Initialization Vector (IV) for the first record is generated by
-     * the handshake protocol, the IV for subsequent records is the
-     * last ciphertext block from the previous record.
-     *
-     * From TLSv1.1, the implicit IV is replaced with an explicit IV to
-     * protect against CBC attacks.
-     *
-     * Differentiating between bad_record_mac and decryption_failed alerts
-     * may permit certain attacks against CBC mode. It is preferable to
-     * uniformly use the bad_record_mac alert to hide the specific type of
-     * the error.
-     */
-    int decrypt(byte[] buf, int offset, int len,
-            int tagLen) throws BadPaddingException {
-        if (cipher == null) {
-            return len;
-        }
-
-        try {
-            int newLen = cipher.update(buf, offset, len, buf, offset);
-            if (newLen != len) {
-                // catch BouncyCastle buffering error
-                throw new RuntimeException("Cipher buffering error " +
-                    "in JCE provider " + cipher.getProvider().getName());
-            }
-            if (debug != null && Debug.isOn("plaintext")) {
-                try {
-                    HexDumpEncoder hd = new HexDumpEncoder();
-
-                    System.out.println(
-                        "Padded plaintext after DECRYPTION:  len = "
-                        + newLen);
-                    hd.encodeBuffer(
-                        new ByteArrayInputStream(buf, offset, newLen),
-                        System.out);
-                } catch (IOException e) { }
-            }
-
-            if (blockSize != 0) {
-                newLen = removePadding(
-                    buf, offset, newLen, tagLen, blockSize, protocolVersion);
-
-                if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
-                    if (newLen < blockSize) {
-                        throw new BadPaddingException("invalid explicit IV");
-                    }
-
-                    // discards the first cipher block, the IV component.
-                    System.arraycopy(buf, offset + blockSize,
-                                     buf, offset, newLen - blockSize);
-
-                    newLen -= blockSize;
-                }
-            }
-            return newLen;
-        } catch (ShortBufferException e) {
-            throw new ArrayIndexOutOfBoundsException(e.toString());
-        }
-    }
-
-
-    /*
-     * Decrypts a block of data, returning the size of the
-     * resulting block if padding was required.  position and limit
-     * point to the end of the decrypted/depadded data.  The initial
-     * limit and new limit may be different, given we may
-     * have stripped off some padding bytes.
-     *
-     *  @see decrypt(byte[], int, int)
-     */
-    int decrypt(ByteBuffer bb, int tagLen) throws BadPaddingException {
-
-        int len = bb.remaining();
-
-        if (cipher == null) {
-            bb.position(bb.limit());
-            return len;
-        }
-
-        try {
-            /*
-             * Decrypt "in-place".
-             */
-            int pos = bb.position();
-            ByteBuffer dup = bb.duplicate();
-            int newLen = cipher.update(dup, bb);
-            if (newLen != len) {
-                // catch BouncyCastle buffering error
-                throw new RuntimeException("Cipher buffering error " +
-                    "in JCE provider " + cipher.getProvider().getName());
-            }
-
-            if (debug != null && Debug.isOn("plaintext")) {
-                try {
-                    HexDumpEncoder hd = new HexDumpEncoder();
-
-                    System.out.println(
-                        "Padded plaintext after DECRYPTION:  len = "
-                        + newLen);
-
-                    hd.encodeBuffer(
-                        (ByteBuffer)bb.duplicate().position(pos), System.out);
-                } catch (IOException e) { }
-            }
-
-            /*
-             * Remove the block padding.
-             */
-            if (blockSize != 0) {
-                bb.position(pos);
-                newLen = removePadding(
-                    bb, tagLen, blockSize, protocolVersion);
-
-                if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
-                    if (newLen < blockSize) {
-                        throw new BadPaddingException("invalid explicit IV");
-                    }
-
-                    // discards the first cipher block, the IV component.
-                    byte[] buf = null;
-                    int limit = bb.limit();
-                    if (bb.hasArray()) {
-                        int arrayOffset = bb.arrayOffset();
-                        buf = bb.array();
-                        System.arraycopy(buf, arrayOffset + pos + blockSize,
-                            buf, arrayOffset + pos, limit - pos - blockSize);
-                        bb.limit(limit - blockSize);
-                    } else {
-                        buf = new byte[limit - pos - blockSize];
-                        bb.position(pos + blockSize);
-                        bb.get(buf);
-                        bb.position(pos);
-                        bb.put(buf);
-                        bb.limit(limit - blockSize);
-                    }
-
-                    // reset the position to the end of the decrypted data
-                    limit = bb.limit();
-                    bb.position(limit);
-                }
-            }
-            return newLen;
-        } catch (ShortBufferException e) {
-            RuntimeException exc = new RuntimeException(e.toString());
-            exc.initCause(e);
-            throw exc;
-        }
-    }
-
-    private static int addPadding(byte[] buf, int offset, int len,
-            int blockSize) {
-        int     newlen = len + 1;
-        byte    pad;
-        int     i;
-
-        if ((newlen % blockSize) != 0) {
-            newlen += blockSize - 1;
-            newlen -= newlen % blockSize;
-        }
-        pad = (byte) (newlen - len);
-
-        if (buf.length < (newlen + offset)) {
-            throw new IllegalArgumentException("no space to pad buffer");
-        }
-
-        /*
-         * TLS version of the padding works for both SSLv3 and TLSv1
-         */
-        for (i = 0, offset += len; i < pad; i++) {
-            buf [offset++] = (byte) (pad - 1);
-        }
-        return newlen;
-    }
-
-    /*
-     * Apply the padding to the buffer.
-     *
-     * Limit is advanced to the new buffer length.
-     * Position is equal to limit.
-     */
-    private static int addPadding(ByteBuffer bb, int blockSize) {
-
-        int     len = bb.remaining();
-        int     offset = bb.position();
-
-        int     newlen = len + 1;
-        byte    pad;
-        int     i;
-
-        if ((newlen % blockSize) != 0) {
-            newlen += blockSize - 1;
-            newlen -= newlen % blockSize;
-        }
-        pad = (byte) (newlen - len);
-
-        /*
-         * Update the limit to what will be padded.
-         */
-        bb.limit(newlen + offset);
-
-        /*
-         * TLS version of the padding works for both SSLv3 and TLSv1
-         */
-        for (i = 0, offset += len; i < pad; i++) {
-            bb.put(offset++, (byte) (pad - 1));
-        }
-
-        bb.position(offset);
-        bb.limit(offset);
-
-        return newlen;
-    }
-
-    /*
-     * A constant-time check of the padding.
-     *
-     * NOTE that we are checking both the padding and the padLen bytes here.
-     *
-     * The caller MUST ensure that the len parameter is a positive number.
-     */
-    private static int[] checkPadding(
-            byte[] buf, int offset, int len, byte pad) {
-
-        if (len <= 0) {
-            throw new RuntimeException("padding len must be positive");
-        }
-
-        // An array of hits is used to prevent Hotspot optimization for
-        // the purpose of a constant-time check.
-        int[] results = {0, 0};    // {missed #, matched #}
-        for (int i = 0; i <= 256;) {
-            for (int j = 0; j < len && i <= 256; j++, i++) {     // j <= i
-                if (buf[offset + j] != pad) {
-                    results[0]++;       // mismatched padding data
-                } else {
-                    results[1]++;       // matched padding data
-                }
-            }
-        }
-
-        return results;
-    }
-
-    /*
-     * A constant-time check of the padding.
-     *
-     * NOTE that we are checking both the padding and the padLen bytes here.
-     *
-     * The caller MUST ensure that the bb parameter has remaining.
-     */
-    private static int[] checkPadding(ByteBuffer bb, byte pad) {
-
-        if (!bb.hasRemaining()) {
-            throw new RuntimeException("hasRemaining() must be positive");
-        }
-
-        // An array of hits is used to prevent Hotspot optimization for
-        // the purpose of a constant-time check.
-        int[] results = {0, 0};    // {missed #, matched #}
-        bb.mark();
-        for (int i = 0; i <= 256; bb.reset()) {
-            for (; bb.hasRemaining() && i <= 256; i++) {
-                if (bb.get() != pad) {
-                    results[0]++;       // mismatched padding data
-                } else {
-                    results[1]++;       // matched padding data
-                }
-            }
-        }
-
-        return results;
-    }
-
-    /*
-     * Typical TLS padding format for a 64 bit block cipher is as follows:
-     *   xx xx xx xx xx xx xx 00
-     *   xx xx xx xx xx xx 01 01
-     *   ...
-     *   xx 06 06 06 06 06 06 06
-     *   07 07 07 07 07 07 07 07
-     * TLS also allows any amount of padding from 1 and 256 bytes as long
-     * as it makes the data a multiple of the block size
-     */
-    private static int removePadding(byte[] buf, int offset, int len,
-            int tagLen, int blockSize,
-            ProtocolVersion protocolVersion) throws BadPaddingException {
-
-        // last byte is length byte (i.e. actual padding length - 1)
-        int padOffset = offset + len - 1;
-        int padLen = buf[padOffset] & 0xFF;
-
-        int newLen = len - (padLen + 1);
-        if ((newLen - tagLen) < 0) {
-            // If the buffer is not long enough to contain the padding plus
-            // a MAC tag, do a dummy constant-time padding check.
-            //
-            // Note that it is a dummy check, so we won't care about what is
-            // the actual padding data.
-            checkPadding(buf, offset, len, (byte)(padLen & 0xFF));
-
-            throw new BadPaddingException("Invalid Padding length: " + padLen);
-        }
-
-        // The padding data should be filled with the padding length value.
-        int[] results = checkPadding(buf, offset + newLen,
-                        padLen + 1, (byte)(padLen & 0xFF));
-        if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
-            if (results[0] != 0) {          // padding data has invalid bytes
-                throw new BadPaddingException("Invalid TLS padding data");
-            }
-        } else { // SSLv3
-            // SSLv3 requires 0 <= length byte < block size
-            // some implementations do 1 <= length byte <= block size,
-            // so accept that as well
-            // v3 does not require any particular value for the other bytes
-            if (padLen > blockSize) {
-                throw new BadPaddingException("Invalid SSLv3 padding");
-            }
-        }
-        return newLen;
-    }
-
-    /*
-     * Position/limit is equal the removed padding.
-     */
-    private static int removePadding(ByteBuffer bb,
-            int tagLen, int blockSize,
-            ProtocolVersion protocolVersion) throws BadPaddingException {
-
-        int len = bb.remaining();
-        int offset = bb.position();
-
-        // last byte is length byte (i.e. actual padding length - 1)
-        int padOffset = offset + len - 1;
-        int padLen = bb.get(padOffset) & 0xFF;
-
-        int newLen = len - (padLen + 1);
-        if ((newLen - tagLen) < 0) {
-            // If the buffer is not long enough to contain the padding plus
-            // a MAC tag, do a dummy constant-time padding check.
-            //
-            // Note that it is a dummy check, so we won't care about what is
-            // the actual padding data.
-            checkPadding(bb.duplicate(), (byte)(padLen & 0xFF));
-
-            throw new BadPaddingException("Invalid Padding length: " + padLen);
-        }
-
-        // The padding data should be filled with the padding length value.
-        int[] results = checkPadding(
-                (ByteBuffer)bb.duplicate().position(offset + newLen),
-                (byte)(padLen & 0xFF));
-        if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
-            if (results[0] != 0) {          // padding data has invalid bytes
-                throw new BadPaddingException("Invalid TLS padding data");
-            }
-        } else { // SSLv3
-            // SSLv3 requires 0 <= length byte < block size
-            // some implementations do 1 <= length byte <= block size,
-            // so accept that as well
-            // v3 does not require any particular value for the other bytes
-            if (padLen > blockSize) {
-                throw new BadPaddingException("Invalid SSLv3 padding");
-            }
-        }
-
-        /*
-         * Reset buffer limit to remove padding.
-         */
-        bb.position(offset + newLen);
-        bb.limit(offset + newLen);
-
-        return newLen;
-    }
-
-    /*
-     * Dispose of any intermediate state in the underlying cipher.
-     * For PKCS11 ciphers, this will release any attached sessions, and
-     * thus make finalization faster.
-     */
-    void dispose() {
-        try {
-            if (cipher != null) {
-                // ignore return value.
-                cipher.doFinal();
-            }
-        } catch (GeneralSecurityException e) {
-            // swallow for now.
-        }
-    }
-
-    /*
-     * Does the cipher use CBC mode?
-     *
-     * @return true if the cipher use CBC mode, false otherwise.
-     */
-    boolean isCBCMode() {
-        return isCBCMode;
-    }
-
-    /**
-     * Is the cipher null?
-     *
-     * @return true if the cipher is null, false otherwise.
-     */
-    boolean isNullCipher() {
-        return cipher == null;
-    }
-
-    /**
-     * Sanity check the length of a fragment before decryption.
-     *
-     * In CBC mode, check that the fragment length is one or multiple times
-     * of the block size of the cipher suite, and is at least one (one is the
-     * smallest size of padding in CBC mode) bigger than the tag size of the
-     * MAC algorithm except the explicit IV size for TLS 1.1 or later.
-     *
-     * In non-CBC mode, check that the fragment length is not less than the
-     * tag size of the MAC algorithm.
-     *
-     * @return true if the length of a fragment matches above requirements
-     */
-    boolean sanityCheck(int tagLen, int fragmentLen) {
-        if (!isCBCMode) {
-            return fragmentLen >= tagLen;
-        }
-
-        if ((fragmentLen % blockSize) == 0) {
-            int minimal = tagLen + 1;
-            minimal = (minimal >= blockSize) ? minimal : blockSize;
-            if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
-                minimal += blockSize;   // plus the size of the explicit IV
-            }
-
-            return (fragmentLen >= minimal);
-        }
-
-        return false;
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/CipherSuite.java b/ojluni/src/main/java/sun/security/ssl/CipherSuite.java
deleted file mode 100755
index 3bf67fa..0000000
--- a/ojluni/src/main/java/sun/security/ssl/CipherSuite.java
+++ /dev/null
@@ -1,1292 +0,0 @@
-/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.util.*;
-
-import java.security.NoSuchAlgorithmException;
-import java.security.InvalidKeyException;
-import java.security.SecureRandom;
-
-import javax.crypto.SecretKey;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-import sun.security.ssl.CipherSuite.*;
-import static sun.security.ssl.CipherSuite.KeyExchange.*;
-import static sun.security.ssl.CipherSuite.PRF.*;
-import static sun.security.ssl.JsseJce.*;
-
-/**
- * An SSL/TLS CipherSuite. Constants for the standard key exchange, cipher,
- * and mac algorithms are also defined in this class.
- *
- * The CipherSuite class and the inner classes defined in this file roughly
- * follow the type safe enum pattern described in Effective Java. This means:
- *
- *  . instances are immutable, classes are final
- *
- *  . there is a unique instance of every value, i.e. there are never two
- *    instances representing the same CipherSuite, etc. This means equality
- *    tests can be performed using == instead of equals() (although that works
- *    as well). [A minor exception are *unsupported* CipherSuites read from a
- *    handshake message, but this is usually irrelevant]
- *
- *  . instances are obtained using the static valueOf() factory methods.
- *
- *  . properties are defined as final variables and made available as
- *    package private variables without method accessors
- *
- *  . if the member variable allowed is false, the given algorithm is either
- *    unavailable or disabled at compile time
- *
- */
-final class CipherSuite implements Comparable {
-
-    // minimum priority for supported CipherSuites
-    final static int SUPPORTED_SUITES_PRIORITY = 1;
-
-    // minimum priority for default enabled CipherSuites
-    final static int DEFAULT_SUITES_PRIORITY = 300;
-
-    // Flag indicating if CipherSuite availability can change dynamically.
-    // This is the case when we rely on a JCE cipher implementation that
-    // may not be available in the installed JCE providers.
-    // It is true because we might not have an ECC implementation.
-    final static boolean DYNAMIC_AVAILABILITY = true;
-
-    private final static boolean ALLOW_ECC = Debug.getBooleanProperty
-        ("com.sun.net.ssl.enableECC", true);
-
-    // Map Integer(id) -> CipherSuite
-    // contains all known CipherSuites
-    private final static Map<Integer,CipherSuite> idMap;
-
-    // Map String(name) -> CipherSuite
-    // contains only supported CipherSuites (i.e. allowed == true)
-    private final static Map<String,CipherSuite> nameMap;
-
-    // Protocol defined CipherSuite name, e.g. SSL_RSA_WITH_RC4_128_MD5
-    // we use TLS_* only for new CipherSuites, still SSL_* for old ones
-    final String name;
-
-    // id in 16 bit MSB format, i.e. 0x0004 for SSL_RSA_WITH_RC4_128_MD5
-    final int id;
-
-    // priority for the internal default preference order. the higher the
-    // better. Each supported CipherSuite *must* have a unique priority.
-    // Ciphersuites with priority >= DEFAULT_SUITES_PRIORITY are enabled
-    // by default
-    final int priority;
-
-    // key exchange, bulk cipher, mac and prf algorithms. See those
-    // classes below.
-    final KeyExchange keyExchange;
-    final BulkCipher cipher;
-    final MacAlg macAlg;
-    final PRF prfAlg;
-
-    // whether a CipherSuite qualifies as exportable under 512/40 bit rules.
-    // TLS 1.1+ (RFC 4346) must not negotiate to these suites.
-    final boolean exportable;
-
-    // true iff implemented and enabled at compile time
-    final boolean allowed;
-
-    // obsoleted since protocol version
-    final int obsoleted;
-
-    // supported since protocol version
-    final int supported;
-
-    /**
-     * Constructor for implemented CipherSuites.
-     */
-    private CipherSuite(String name, int id, int priority,
-            KeyExchange keyExchange, BulkCipher cipher,
-            boolean allowed, int obsoleted, int supported, PRF prfAlg) {
-        this.name = name;
-        this.id = id;
-        this.priority = priority;
-        this.keyExchange = keyExchange;
-        this.cipher = cipher;
-        this.exportable = cipher.exportable;
-        if (name.endsWith("_MD5")) {
-            macAlg = M_MD5;
-        } else if (name.endsWith("_SHA")) {
-            macAlg = M_SHA;
-        } else if (name.endsWith("_SHA256")) {
-            macAlg = M_SHA256;
-        } else if (name.endsWith("_SHA384")) {
-            macAlg = M_SHA384;
-        } else if (name.endsWith("_NULL")) {
-            macAlg = M_NULL;
-        } else if (name.endsWith("_SCSV")) {
-            macAlg = M_NULL;
-        } else {
-            throw new IllegalArgumentException
-                    ("Unknown MAC algorithm for ciphersuite " + name);
-        }
-
-        allowed &= keyExchange.allowed;
-        allowed &= cipher.allowed;
-        this.allowed = allowed;
-        this.obsoleted = obsoleted;
-        this.supported = supported;
-        this.prfAlg = prfAlg;
-    }
-
-    /**
-     * Constructor for unimplemented CipherSuites.
-     */
-    private CipherSuite(String name, int id) {
-        this.name = name;
-        this.id = id;
-        this.allowed = false;
-
-        this.priority = 0;
-        this.keyExchange = null;
-        this.cipher = null;
-        this.macAlg = null;
-        this.exportable = false;
-        this.obsoleted = ProtocolVersion.LIMIT_MAX_VALUE;
-        this.supported = ProtocolVersion.LIMIT_MIN_VALUE;
-        this.prfAlg = P_NONE;
-    }
-
-    /**
-     * Return whether this CipherSuite is available for use. A
-     * CipherSuite may be unavailable even if it is supported
-     * (i.e. allowed == true) if the required JCE cipher is not installed.
-     * In some configuration, this situation may change over time, call
-     * CipherSuiteList.clearAvailableCache() before this method to obtain
-     * the most current status.
-     */
-    boolean isAvailable() {
-        return allowed && keyExchange.isAvailable() && cipher.isAvailable();
-    }
-
-    boolean isNegotiable() {
-        return this != C_SCSV && isAvailable();
-    }
-
-    /**
-     * Compares CipherSuites based on their priority. Has the effect of
-     * sorting CipherSuites when put in a sorted collection, which is
-     * used by CipherSuiteList. Follows standard Comparable contract.
-     *
-     * Note that for unsupported CipherSuites parsed from a handshake
-     * message we violate the equals() contract.
-     */
-    public int compareTo(Object o) {
-        return ((CipherSuite)o).priority - priority;
-    }
-
-    /**
-     * Returns this.name.
-     */
-    public String toString() {
-        return name;
-    }
-
-    /**
-     * Return a CipherSuite for the given name. The returned CipherSuite
-     * is supported by this implementation but may not actually be
-     * currently useable. See isAvailable().
-     *
-     * @exception IllegalArgumentException if the CipherSuite is unknown or
-     * unsupported.
-     */
-    static CipherSuite valueOf(String s) {
-        if (s == null) {
-            throw new IllegalArgumentException("Name must not be null");
-        }
-
-        CipherSuite c = nameMap.get(s);
-        if ((c == null) || (c.allowed == false)) {
-            throw new IllegalArgumentException("Unsupported ciphersuite " + s);
-        }
-
-        return c;
-    }
-
-    /**
-     * Return a CipherSuite with the given ID. A temporary object is
-     * constructed if the ID is unknown. Use isAvailable() to verify that
-     * the CipherSuite can actually be used.
-     */
-    static CipherSuite valueOf(int id1, int id2) {
-        id1 &= 0xff;
-        id2 &= 0xff;
-        int id = (id1 << 8) | id2;
-        CipherSuite c = idMap.get(id);
-        if (c == null) {
-            String h1 = Integer.toString(id1, 16);
-            String h2 = Integer.toString(id2, 16);
-            c = new CipherSuite("Unknown 0x" + h1 + ":0x" + h2, id);
-        }
-        return c;
-    }
-
-    // for use by CipherSuiteList only
-    static Collection<CipherSuite> allowedCipherSuites() {
-        return nameMap.values();
-    }
-
-    /*
-     * Use this method when all of the values need to be specified.
-     * This is primarily used when defining a new ciphersuite for
-     * TLS 1.2+ that doesn't use the "default" PRF.
-     */
-    private static void add(String name, int id, int priority,
-            KeyExchange keyExchange, BulkCipher cipher,
-            boolean allowed, int obsoleted, int supported, PRF prf) {
-
-        CipherSuite c = new CipherSuite(name, id, priority, keyExchange,
-            cipher, allowed, obsoleted, supported, prf);
-        if (idMap.put(id, c) != null) {
-            throw new RuntimeException("Duplicate ciphersuite definition: "
-                                        + id + ", " + name);
-        }
-        if (c.allowed) {
-            if (nameMap.put(name, c) != null) {
-                throw new RuntimeException("Duplicate ciphersuite definition: "
-                                            + id + ", " + name);
-            }
-        }
-    }
-
-    /*
-     * Use this method when there is no lower protocol limit where this
-     * suite can be used, and the PRF is P_SHA256.  That is, the
-     * existing ciphersuites.  From RFC 5246:
-     *
-     *     All cipher suites in this document use P_SHA256.
-     */
-    private static void add(String name, int id, int priority,
-            KeyExchange keyExchange, BulkCipher cipher,
-            boolean allowed, int obsoleted) {
-        // If this is an obsoleted suite, then don't let the TLS 1.2
-        // protocol have a valid PRF value.
-        PRF prf = P_SHA256;
-        if (obsoleted < ProtocolVersion.TLS12.v) {
-            prf = P_NONE;
-        }
-
-        add(name, id, priority, keyExchange, cipher, allowed, obsoleted,
-            ProtocolVersion.LIMIT_MIN_VALUE, prf);
-    }
-
-    /*
-     * Use this method when there is no upper protocol limit.  That is,
-     * suites which have not been obsoleted.
-     */
-    private static void add(String name, int id, int priority,
-            KeyExchange keyExchange, BulkCipher cipher, boolean allowed) {
-        add(name, id, priority, keyExchange,
-            cipher, allowed, ProtocolVersion.LIMIT_MAX_VALUE);
-    }
-
-    /*
-     * Use this method to define an unimplemented suite.  This provides
-     * a number<->name mapping that can be used for debugging.
-     */
-    private static void add(String name, int id) {
-        CipherSuite c = new CipherSuite(name, id);
-        if (idMap.put(id, c) != null) {
-            throw new RuntimeException("Duplicate ciphersuite definition: "
-                                        + id + ", " + name);
-        }
-    }
-
-    /**
-     * An SSL/TLS key exchange algorithm.
-     */
-    static enum KeyExchange {
-
-        // key exchange algorithms
-        K_NULL       ("NULL",       false),
-        K_RSA        ("RSA",        true),
-        K_RSA_EXPORT ("RSA_EXPORT", true),
-        K_DH_RSA     ("DH_RSA",     false),
-        K_DH_DSS     ("DH_DSS",     false),
-        K_DHE_DSS    ("DHE_DSS",    true),
-        K_DHE_RSA    ("DHE_RSA",    true),
-        K_DH_ANON    ("DH_anon",    true),
-
-        K_ECDH_ECDSA ("ECDH_ECDSA",  ALLOW_ECC),
-        K_ECDH_RSA   ("ECDH_RSA",    ALLOW_ECC),
-        K_ECDHE_ECDSA("ECDHE_ECDSA", ALLOW_ECC),
-        K_ECDHE_RSA  ("ECDHE_RSA",   ALLOW_ECC),
-        K_ECDH_ANON  ("ECDH_anon",   ALLOW_ECC),
-
-        // Kerberos cipher suites
-        K_KRB5       ("KRB5", true),
-        K_KRB5_EXPORT("KRB5_EXPORT", true),
-
-        // renegotiation protection request signaling cipher suite
-        K_SCSV       ("SCSV",        true);
-
-        // name of the key exchange algorithm, e.g. DHE_DSS
-        final String name;
-        final boolean allowed;
-        private final boolean alwaysAvailable;
-
-        KeyExchange(String name, boolean allowed) {
-            this.name = name;
-            this.allowed = allowed;
-            this.alwaysAvailable = allowed &&
-                (!name.startsWith("EC")) && (!name.startsWith("KRB"));
-        }
-
-        boolean isAvailable() {
-            if (alwaysAvailable) {
-                return true;
-            }
-
-            if (name.startsWith("EC")) {
-                return (allowed && JsseJce.isEcAvailable());
-            } else if (name.startsWith("KRB")) {
-                return (allowed && JsseJce.isKerberosAvailable());
-            } else {
-                return allowed;
-            }
-        }
-
-        public String toString() {
-            return name;
-        }
-    }
-
-    /**
-     * An SSL/TLS bulk cipher algorithm. One instance per combination of
-     * cipher and key length.
-     *
-     * Also contains a factory method to obtain in initialized CipherBox
-     * for this algorithm.
-     */
-    final static class BulkCipher {
-
-        // Map BulkCipher -> Boolean(available)
-        private final static Map<BulkCipher,Boolean> availableCache =
-                                            new HashMap<>(8);
-
-        // descriptive name including key size, e.g. AES/128
-        final String description;
-
-        // JCE cipher transformation string, e.g. AES/CBC/NoPadding
-        final String transformation;
-
-        // algorithm name, e.g. AES
-        final String algorithm;
-
-        // supported and compile time enabled. Also see isAvailable()
-        final boolean allowed;
-
-        // number of bytes of entropy in the key
-        final int keySize;
-
-        // length of the actual cipher key in bytes.
-        // for non-exportable ciphers, this is the same as keySize
-        final int expandedKeySize;
-
-        // size of the IV (also block size)
-        final int ivSize;
-
-        // exportable under 512/40 bit rules
-        final boolean exportable;
-
-        // Is the cipher algorithm of Cipher Block Chaining (CBC) mode?
-        final boolean isCBCMode;
-
-        BulkCipher(String transformation, int keySize,
-                int expandedKeySize, int ivSize, boolean allowed) {
-            this.transformation = transformation;
-            String[] splits = transformation.split("/");
-            this.algorithm = splits[0];
-            this.isCBCMode =
-                splits.length <= 1 ? false : "CBC".equalsIgnoreCase(splits[1]);
-            this.description = this.algorithm + "/" + (keySize << 3);
-            this.keySize = keySize;
-            this.ivSize = ivSize;
-            this.allowed = allowed;
-
-            this.expandedKeySize = expandedKeySize;
-            this.exportable = true;
-        }
-
-        BulkCipher(String transformation, int keySize,
-                int ivSize, boolean allowed) {
-            this.transformation = transformation;
-            String[] splits = transformation.split("/");
-            this.algorithm = splits[0];
-            this.isCBCMode =
-                splits.length <= 1 ? false : "CBC".equalsIgnoreCase(splits[1]);
-            this.description = this.algorithm + "/" + (keySize << 3);
-            this.keySize = keySize;
-            this.ivSize = ivSize;
-            this.allowed = allowed;
-
-            this.expandedKeySize = keySize;
-            this.exportable = false;
-        }
-
-        /**
-         * Return an initialized CipherBox for this BulkCipher.
-         * IV must be null for stream ciphers.
-         *
-         * @exception NoSuchAlgorithmException if anything goes wrong
-         */
-        CipherBox newCipher(ProtocolVersion version, SecretKey key,
-                IvParameterSpec iv, SecureRandom random,
-                boolean encrypt) throws NoSuchAlgorithmException {
-            return CipherBox.newCipherBox(version, this,
-                                            key, iv, random, encrypt);
-        }
-
-        /**
-         * Test if this bulk cipher is available. For use by CipherSuite.
-         *
-         * Currently all supported ciphers except AES are always available
-         * via the JSSE internal implementations. We also assume AES/128
-         * is always available since it is shipped with the SunJCE provider.
-         * However, AES/256 is unavailable when the default JCE policy
-         * jurisdiction files are installed because of key length restrictions.
-         */
-        boolean isAvailable() {
-            if (allowed == false) {
-                return false;
-            }
-            if (this == B_AES_256) {
-                return isAvailable(this);
-            }
-
-            // always available
-            return true;
-        }
-
-        // for use by CipherSuiteList.clearAvailableCache();
-        static synchronized void clearAvailableCache() {
-            if (DYNAMIC_AVAILABILITY) {
-                availableCache.clear();
-            }
-        }
-
-        private static synchronized boolean isAvailable(BulkCipher cipher) {
-            Boolean b = availableCache.get(cipher);
-            if (b == null) {
-                try {
-                    SecretKey key = new SecretKeySpec
-                        (new byte[cipher.expandedKeySize], cipher.algorithm);
-                    IvParameterSpec iv =
-                        new IvParameterSpec(new byte[cipher.ivSize]);
-                    cipher.newCipher(ProtocolVersion.DEFAULT,
-                                                key, iv, null, true);
-                    b = Boolean.TRUE;
-                } catch (NoSuchAlgorithmException e) {
-                    b = Boolean.FALSE;
-                }
-                availableCache.put(cipher, b);
-            }
-            return b.booleanValue();
-        }
-
-        public String toString() {
-            return description;
-        }
-    }
-
-    /**
-     * An SSL/TLS key MAC algorithm.
-     *
-     * Also contains a factory method to obtain an initialized MAC
-     * for this algorithm.
-     */
-    final static class MacAlg {
-
-        // descriptive name, e.g. MD5
-        final String name;
-
-        // size of the MAC value (and MAC key) in bytes
-        final int size;
-
-        // block size of the underlying hash algorithm
-        final int hashBlockSize;
-
-        // minimal padding size of the underlying hash algorithm
-        final int minimalPaddingSize;
-
-        MacAlg(String name, int size,
-                int hashBlockSize, int minimalPaddingSize) {
-            this.name = name;
-            this.size = size;
-            this.hashBlockSize = hashBlockSize;
-            this.minimalPaddingSize = minimalPaddingSize;
-        }
-
-        /**
-         * Return an initialized MAC for this MacAlg. ProtocolVersion
-         * must either be SSL30 (SSLv3 custom MAC) or TLS10 (std. HMAC).
-         *
-         * @exception NoSuchAlgorithmException if anything goes wrong
-         */
-        MAC newMac(ProtocolVersion protocolVersion, SecretKey secret)
-                throws NoSuchAlgorithmException, InvalidKeyException {
-            return new MAC(this, protocolVersion, secret);
-        }
-
-        public String toString() {
-            return name;
-        }
-    }
-
-    // export strength ciphers
-    final static BulkCipher B_NULL    =
-                        new BulkCipher("NULL",         0,  0, 0, true);
-    final static BulkCipher B_RC4_40  =
-                        new BulkCipher(CIPHER_RC4,     5, 16, 0, true);
-    final static BulkCipher B_RC2_40  =
-                        new BulkCipher("RC2",          5, 16, 8, false);
-    final static BulkCipher B_DES_40  =
-                        new BulkCipher(CIPHER_DES,     5,  8, 8, true);
-
-    // domestic strength ciphers
-    final static BulkCipher B_RC4_128 =
-                        new BulkCipher(CIPHER_RC4,     16,  0, true);
-    final static BulkCipher B_DES     =
-                        new BulkCipher(CIPHER_DES,      8,  8, true);
-    final static BulkCipher B_3DES    =
-                        new BulkCipher(CIPHER_3DES,    24,  8, true);
-    final static BulkCipher B_IDEA    =
-                        new BulkCipher("IDEA",         16,  8, false);
-    final static BulkCipher B_AES_128 =
-                        new BulkCipher(CIPHER_AES,     16, 16, true);
-    final static BulkCipher B_AES_256 =
-                        new BulkCipher(CIPHER_AES,     32, 16, true);
-
-    // MACs
-    final static MacAlg M_NULL    = new MacAlg("NULL",     0,   0,   0);
-    final static MacAlg M_MD5     = new MacAlg("MD5",     16,  64,   9);
-    final static MacAlg M_SHA     = new MacAlg("SHA",     20,  64,   9);
-    final static MacAlg M_SHA256  = new MacAlg("SHA256",  32,  64,   9);
-    final static MacAlg M_SHA384  = new MacAlg("SHA384",  48, 128,  17);
-
-    /**
-     * PRFs (PseudoRandom Function) from TLS specifications.
-     *
-     * TLS 1.1- uses a single MD5/SHA1-based PRF algorithm for generating
-     * the necessary material.
-     *
-     * In TLS 1.2+, all existing/known CipherSuites use SHA256, however
-     * new Ciphersuites (e.g. RFC 5288) can define specific PRF hash
-     * algorithms.
-     */
-    static enum PRF {
-
-        // PRF algorithms
-        P_NONE(     "NONE",  0,   0),
-        P_SHA256("SHA-256", 32,  64),
-        P_SHA384("SHA-384", 48, 128),
-        P_SHA512("SHA-512", 64, 128);  // not currently used.
-
-        // PRF characteristics
-        private final String prfHashAlg;
-        private final int prfHashLength;
-        private final int prfBlockSize;
-
-        PRF(String prfHashAlg, int prfHashLength, int prfBlockSize) {
-            this.prfHashAlg = prfHashAlg;
-            this.prfHashLength = prfHashLength;
-            this.prfBlockSize = prfBlockSize;
-        }
-
-        String getPRFHashAlg() {
-            return prfHashAlg;
-        }
-
-        int getPRFHashLength() {
-            return prfHashLength;
-        }
-
-        int getPRFBlockSize() {
-            return prfBlockSize;
-        }
-    }
-
-    static {
-        idMap = new HashMap<Integer,CipherSuite>();
-        nameMap = new HashMap<String,CipherSuite>();
-
-        final boolean F = false;
-        final boolean T = true;
-        // N: ciphersuites only allowed if we are not in FIPS mode
-        final boolean N = (SunJSSE.isFIPS() == false);
-
-        /*
-         * TLS Cipher Suite Registry, as of August 2010.
-         *
-         * http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
-         *
-         * Range      Registration Procedures   Notes
-         * 000-191    Standards Action          Refers to value of first byte
-         * 192-254    Specification Required    Refers to value of first byte
-         * 255        Reserved for Private Use  Refers to value of first byte
-         *
-         * Value      Description                               Reference
-         * 0x00,0x00  TLS_NULL_WITH_NULL_NULL                   [RFC5246]
-         * 0x00,0x01  TLS_RSA_WITH_NULL_MD5                     [RFC5246]
-         * 0x00,0x02  TLS_RSA_WITH_NULL_SHA                     [RFC5246]
-         * 0x00,0x03  TLS_RSA_EXPORT_WITH_RC4_40_MD5            [RFC4346]
-         * 0x00,0x04  TLS_RSA_WITH_RC4_128_MD5                  [RFC5246]
-         * 0x00,0x05  TLS_RSA_WITH_RC4_128_SHA                  [RFC5246]
-         * 0x00,0x06  TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5        [RFC4346]
-         * 0x00,0x07  TLS_RSA_WITH_IDEA_CBC_SHA                 [RFC5469]
-         * 0x00,0x08  TLS_RSA_EXPORT_WITH_DES40_CBC_SHA         [RFC4346]
-         * 0x00,0x09  TLS_RSA_WITH_DES_CBC_SHA                  [RFC5469]
-         * 0x00,0x0A  TLS_RSA_WITH_3DES_EDE_CBC_SHA             [RFC5246]
-         * 0x00,0x0B  TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA      [RFC4346]
-         * 0x00,0x0C  TLS_DH_DSS_WITH_DES_CBC_SHA               [RFC5469]
-         * 0x00,0x0D  TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA          [RFC5246]
-         * 0x00,0x0E  TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA      [RFC4346]
-         * 0x00,0x0F  TLS_DH_RSA_WITH_DES_CBC_SHA               [RFC5469]
-         * 0x00,0x10  TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA          [RFC5246]
-         * 0x00,0x11  TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA     [RFC4346]
-         * 0x00,0x12  TLS_DHE_DSS_WITH_DES_CBC_SHA              [RFC5469]
-         * 0x00,0x13  TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA         [RFC5246]
-         * 0x00,0x14  TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA     [RFC4346]
-         * 0x00,0x15  TLS_DHE_RSA_WITH_DES_CBC_SHA              [RFC5469]
-         * 0x00,0x16  TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA         [RFC5246]
-         * 0x00,0x17  TLS_DH_anon_EXPORT_WITH_RC4_40_MD5        [RFC4346]
-         * 0x00,0x18  TLS_DH_anon_WITH_RC4_128_MD5              [RFC5246]
-         * 0x00,0x19  TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA     [RFC4346]
-         * 0x00,0x1A  TLS_DH_anon_WITH_DES_CBC_SHA              [RFC5469]
-         * 0x00,0x1B  TLS_DH_anon_WITH_3DES_EDE_CBC_SHA         [RFC5246]
-         * 0x00,0x1C-1D Reserved to avoid conflicts with SSLv3  [RFC5246]
-         * 0x00,0x1E  TLS_KRB5_WITH_DES_CBC_SHA                 [RFC2712]
-         * 0x00,0x1F  TLS_KRB5_WITH_3DES_EDE_CBC_SHA            [RFC2712]
-         * 0x00,0x20  TLS_KRB5_WITH_RC4_128_SHA                 [RFC2712]
-         * 0x00,0x21  TLS_KRB5_WITH_IDEA_CBC_SHA                [RFC2712]
-         * 0x00,0x22  TLS_KRB5_WITH_DES_CBC_MD5                 [RFC2712]
-         * 0x00,0x23  TLS_KRB5_WITH_3DES_EDE_CBC_MD5            [RFC2712]
-         * 0x00,0x24  TLS_KRB5_WITH_RC4_128_MD5                 [RFC2712]
-         * 0x00,0x25  TLS_KRB5_WITH_IDEA_CBC_MD5                [RFC2712]
-         * 0x00,0x26  TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA       [RFC2712]
-         * 0x00,0x27  TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA       [RFC2712]
-         * 0x00,0x28  TLS_KRB5_EXPORT_WITH_RC4_40_SHA           [RFC2712]
-         * 0x00,0x29  TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5       [RFC2712]
-         * 0x00,0x2A  TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5       [RFC2712]
-         * 0x00,0x2B  TLS_KRB5_EXPORT_WITH_RC4_40_MD5           [RFC2712]
-         * 0x00,0x2C  TLS_PSK_WITH_NULL_SHA                     [RFC4785]
-         * 0x00,0x2D  TLS_DHE_PSK_WITH_NULL_SHA                 [RFC4785]
-         * 0x00,0x2E  TLS_RSA_PSK_WITH_NULL_SHA                 [RFC4785]
-         * 0x00,0x2F  TLS_RSA_WITH_AES_128_CBC_SHA              [RFC5246]
-         * 0x00,0x30  TLS_DH_DSS_WITH_AES_128_CBC_SHA           [RFC5246]
-         * 0x00,0x31  TLS_DH_RSA_WITH_AES_128_CBC_SHA           [RFC5246]
-         * 0x00,0x32  TLS_DHE_DSS_WITH_AES_128_CBC_SHA          [RFC5246]
-         * 0x00,0x33  TLS_DHE_RSA_WITH_AES_128_CBC_SHA          [RFC5246]
-         * 0x00,0x34  TLS_DH_anon_WITH_AES_128_CBC_SHA          [RFC5246]
-         * 0x00,0x35  TLS_RSA_WITH_AES_256_CBC_SHA              [RFC5246]
-         * 0x00,0x36  TLS_DH_DSS_WITH_AES_256_CBC_SHA           [RFC5246]
-         * 0x00,0x37  TLS_DH_RSA_WITH_AES_256_CBC_SHA           [RFC5246]
-         * 0x00,0x38  TLS_DHE_DSS_WITH_AES_256_CBC_SHA          [RFC5246]
-         * 0x00,0x39  TLS_DHE_RSA_WITH_AES_256_CBC_SHA          [RFC5246]
-         * 0x00,0x3A  TLS_DH_anon_WITH_AES_256_CBC_SHA          [RFC5246]
-         * 0x00,0x3B  TLS_RSA_WITH_NULL_SHA256                  [RFC5246]
-         * 0x00,0x3C  TLS_RSA_WITH_AES_128_CBC_SHA256           [RFC5246]
-         * 0x00,0x3D  TLS_RSA_WITH_AES_256_CBC_SHA256           [RFC5246]
-         * 0x00,0x3E  TLS_DH_DSS_WITH_AES_128_CBC_SHA256        [RFC5246]
-         * 0x00,0x3F  TLS_DH_RSA_WITH_AES_128_CBC_SHA256        [RFC5246]
-         * 0x00,0x40  TLS_DHE_DSS_WITH_AES_128_CBC_SHA256       [RFC5246]
-         * 0x00,0x41  TLS_RSA_WITH_CAMELLIA_128_CBC_SHA         [RFC5932]
-         * 0x00,0x42  TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA      [RFC5932]
-         * 0x00,0x43  TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA      [RFC5932]
-         * 0x00,0x44  TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA     [RFC5932]
-         * 0x00,0x45  TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA     [RFC5932]
-         * 0x00,0x46  TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA     [RFC5932]
-         * 0x00,0x47-4F Reserved to avoid conflicts with
-         *            deployed implementations                  [Pasi_Eronen]
-         * 0x00,0x50-58 Reserved to avoid conflicts             [Pasi Eronen]
-         * 0x00,0x59-5C Reserved to avoid conflicts with
-         *            deployed implementations                  [Pasi_Eronen]
-         * 0x00,0x5D-5F Unassigned
-         * 0x00,0x60-66 Reserved to avoid conflicts with widely
-         *            deployed implementations                  [Pasi_Eronen]
-         * 0x00,0x67  TLS_DHE_RSA_WITH_AES_128_CBC_SHA256       [RFC5246]
-         * 0x00,0x68  TLS_DH_DSS_WITH_AES_256_CBC_SHA256        [RFC5246]
-         * 0x00,0x69  TLS_DH_RSA_WITH_AES_256_CBC_SHA256        [RFC5246]
-         * 0x00,0x6A  TLS_DHE_DSS_WITH_AES_256_CBC_SHA256       [RFC5246]
-         * 0x00,0x6B  TLS_DHE_RSA_WITH_AES_256_CBC_SHA256       [RFC5246]
-         * 0x00,0x6C  TLS_DH_anon_WITH_AES_128_CBC_SHA256       [RFC5246]
-         * 0x00,0x6D  TLS_DH_anon_WITH_AES_256_CBC_SHA256       [RFC5246]
-         * 0x00,0x6E-83 Unassigned
-         * 0x00,0x84  TLS_RSA_WITH_CAMELLIA_256_CBC_SHA         [RFC5932]
-         * 0x00,0x85  TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA      [RFC5932]
-         * 0x00,0x86  TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA      [RFC5932]
-         * 0x00,0x87  TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA     [RFC5932]
-         * 0x00,0x88  TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA     [RFC5932]
-         * 0x00,0x89  TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA     [RFC5932]
-         * 0x00,0x8A  TLS_PSK_WITH_RC4_128_SHA                  [RFC4279]
-         * 0x00,0x8B  TLS_PSK_WITH_3DES_EDE_CBC_SHA             [RFC4279]
-         * 0x00,0x8C  TLS_PSK_WITH_AES_128_CBC_SHA              [RFC4279]
-         * 0x00,0x8D  TLS_PSK_WITH_AES_256_CBC_SHA              [RFC4279]
-         * 0x00,0x8E  TLS_DHE_PSK_WITH_RC4_128_SHA              [RFC4279]
-         * 0x00,0x8F  TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA         [RFC4279]
-         * 0x00,0x90  TLS_DHE_PSK_WITH_AES_128_CBC_SHA          [RFC4279]
-         * 0x00,0x91  TLS_DHE_PSK_WITH_AES_256_CBC_SHA          [RFC4279]
-         * 0x00,0x92  TLS_RSA_PSK_WITH_RC4_128_SHA              [RFC4279]
-         * 0x00,0x93  TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA         [RFC4279]
-         * 0x00,0x94  TLS_RSA_PSK_WITH_AES_128_CBC_SHA          [RFC4279]
-         * 0x00,0x95  TLS_RSA_PSK_WITH_AES_256_CBC_SHA          [RFC4279]
-         * 0x00,0x96  TLS_RSA_WITH_SEED_CBC_SHA                 [RFC4162]
-         * 0x00,0x97  TLS_DH_DSS_WITH_SEED_CBC_SHA              [RFC4162]
-         * 0x00,0x98  TLS_DH_RSA_WITH_SEED_CBC_SHA              [RFC4162]
-         * 0x00,0x99  TLS_DHE_DSS_WITH_SEED_CBC_SHA             [RFC4162]
-         * 0x00,0x9A  TLS_DHE_RSA_WITH_SEED_CBC_SHA             [RFC4162]
-         * 0x00,0x9B  TLS_DH_anon_WITH_SEED_CBC_SHA             [RFC4162]
-         * 0x00,0x9C  TLS_RSA_WITH_AES_128_GCM_SHA256           [RFC5288]
-         * 0x00,0x9D  TLS_RSA_WITH_AES_256_GCM_SHA384           [RFC5288]
-         * 0x00,0x9E  TLS_DHE_RSA_WITH_AES_128_GCM_SHA256       [RFC5288]
-         * 0x00,0x9F  TLS_DHE_RSA_WITH_AES_256_GCM_SHA384       [RFC5288]
-         * 0x00,0xA0  TLS_DH_RSA_WITH_AES_128_GCM_SHA256        [RFC5288]
-         * 0x00,0xA1  TLS_DH_RSA_WITH_AES_256_GCM_SHA384        [RFC5288]
-         * 0x00,0xA2  TLS_DHE_DSS_WITH_AES_128_GCM_SHA256       [RFC5288]
-         * 0x00,0xA3  TLS_DHE_DSS_WITH_AES_256_GCM_SHA384       [RFC5288]
-         * 0x00,0xA4  TLS_DH_DSS_WITH_AES_128_GCM_SHA256        [RFC5288]
-         * 0x00,0xA5  TLS_DH_DSS_WITH_AES_256_GCM_SHA384        [RFC5288]
-         * 0x00,0xA6  TLS_DH_anon_WITH_AES_128_GCM_SHA256       [RFC5288]
-         * 0x00,0xA7  TLS_DH_anon_WITH_AES_256_GCM_SHA384       [RFC5288]
-         * 0x00,0xA8  TLS_PSK_WITH_AES_128_GCM_SHA256           [RFC5487]
-         * 0x00,0xA9  TLS_PSK_WITH_AES_256_GCM_SHA384           [RFC5487]
-         * 0x00,0xAA  TLS_DHE_PSK_WITH_AES_128_GCM_SHA256       [RFC5487]
-         * 0x00,0xAB  TLS_DHE_PSK_WITH_AES_256_GCM_SHA384       [RFC5487]
-         * 0x00,0xAC  TLS_RSA_PSK_WITH_AES_128_GCM_SHA256       [RFC5487]
-         * 0x00,0xAD  TLS_RSA_PSK_WITH_AES_256_GCM_SHA384       [RFC5487]
-         * 0x00,0xAE  TLS_PSK_WITH_AES_128_CBC_SHA256           [RFC5487]
-         * 0x00,0xAF  TLS_PSK_WITH_AES_256_CBC_SHA384           [RFC5487]
-         * 0x00,0xB0  TLS_PSK_WITH_NULL_SHA256                  [RFC5487]
-         * 0x00,0xB1  TLS_PSK_WITH_NULL_SHA384                  [RFC5487]
-         * 0x00,0xB2  TLS_DHE_PSK_WITH_AES_128_CBC_SHA256       [RFC5487]
-         * 0x00,0xB3  TLS_DHE_PSK_WITH_AES_256_CBC_SHA384       [RFC5487]
-         * 0x00,0xB4  TLS_DHE_PSK_WITH_NULL_SHA256              [RFC5487]
-         * 0x00,0xB5  TLS_DHE_PSK_WITH_NULL_SHA384              [RFC5487]
-         * 0x00,0xB6  TLS_RSA_PSK_WITH_AES_128_CBC_SHA256       [RFC5487]
-         * 0x00,0xB7  TLS_RSA_PSK_WITH_AES_256_CBC_SHA384       [RFC5487]
-         * 0x00,0xB8  TLS_RSA_PSK_WITH_NULL_SHA256              [RFC5487]
-         * 0x00,0xB9  TLS_RSA_PSK_WITH_NULL_SHA384              [RFC5487]
-         * 0x00,0xBA  TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256      [RFC5932]
-         * 0x00,0xBB  TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256   [RFC5932]
-         * 0x00,0xBC  TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256   [RFC5932]
-         * 0x00,0xBD  TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256  [RFC5932]
-         * 0x00,0xBE  TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256  [RFC5932]
-         * 0x00,0xBF  TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256  [RFC5932]
-         * 0x00,0xC0  TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256      [RFC5932]
-         * 0x00,0xC1  TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256   [RFC5932]
-         * 0x00,0xC2  TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256   [RFC5932]
-         * 0x00,0xC3  TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256  [RFC5932]
-         * 0x00,0xC4  TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256  [RFC5932]
-         * 0x00,0xC5  TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256  [RFC5932]
-         * 0x00,0xC6-FE         Unassigned
-         * 0x00,0xFF  TLS_EMPTY_RENEGOTIATION_INFO_SCSV         [RFC5746]
-         * 0x01-BF,*  Unassigned
-         * 0xC0,0x01  TLS_ECDH_ECDSA_WITH_NULL_SHA              [RFC4492]
-         * 0xC0,0x02  TLS_ECDH_ECDSA_WITH_RC4_128_SHA           [RFC4492]
-         * 0xC0,0x03  TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA      [RFC4492]
-         * 0xC0,0x04  TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA       [RFC4492]
-         * 0xC0,0x05  TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA       [RFC4492]
-         * 0xC0,0x06  TLS_ECDHE_ECDSA_WITH_NULL_SHA             [RFC4492]
-         * 0xC0,0x07  TLS_ECDHE_ECDSA_WITH_RC4_128_SHA          [RFC4492]
-         * 0xC0,0x08  TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA     [RFC4492]
-         * 0xC0,0x09  TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA      [RFC4492]
-         * 0xC0,0x0A  TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA      [RFC4492]
-         * 0xC0,0x0B  TLS_ECDH_RSA_WITH_NULL_SHA                [RFC4492]
-         * 0xC0,0x0C  TLS_ECDH_RSA_WITH_RC4_128_SHA             [RFC4492]
-         * 0xC0,0x0D  TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA        [RFC4492]
-         * 0xC0,0x0E  TLS_ECDH_RSA_WITH_AES_128_CBC_SHA         [RFC4492]
-         * 0xC0,0x0F  TLS_ECDH_RSA_WITH_AES_256_CBC_SHA         [RFC4492]
-         * 0xC0,0x10  TLS_ECDHE_RSA_WITH_NULL_SHA               [RFC4492]
-         * 0xC0,0x11  TLS_ECDHE_RSA_WITH_RC4_128_SHA            [RFC4492]
-         * 0xC0,0x12  TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA       [RFC4492]
-         * 0xC0,0x13  TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA        [RFC4492]
-         * 0xC0,0x14  TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA        [RFC4492]
-         * 0xC0,0x15  TLS_ECDH_anon_WITH_NULL_SHA               [RFC4492]
-         * 0xC0,0x16  TLS_ECDH_anon_WITH_RC4_128_SHA            [RFC4492]
-         * 0xC0,0x17  TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA       [RFC4492]
-         * 0xC0,0x18  TLS_ECDH_anon_WITH_AES_128_CBC_SHA        [RFC4492]
-         * 0xC0,0x19  TLS_ECDH_anon_WITH_AES_256_CBC_SHA        [RFC4492]
-         * 0xC0,0x1A  TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA         [RFC5054]
-         * 0xC0,0x1B  TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA     [RFC5054]
-         * 0xC0,0x1C  TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA     [RFC5054]
-         * 0xC0,0x1D  TLS_SRP_SHA_WITH_AES_128_CBC_SHA          [RFC5054]
-         * 0xC0,0x1E  TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA      [RFC5054]
-         * 0xC0,0x1F  TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA      [RFC5054]
-         * 0xC0,0x20  TLS_SRP_SHA_WITH_AES_256_CBC_SHA          [RFC5054]
-         * 0xC0,0x21  TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA      [RFC5054]
-         * 0xC0,0x22  TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA      [RFC5054]
-         * 0xC0,0x23  TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256   [RFC5289]
-         * 0xC0,0x24  TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384   [RFC5289]
-         * 0xC0,0x25  TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256    [RFC5289]
-         * 0xC0,0x26  TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384    [RFC5289]
-         * 0xC0,0x27  TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256     [RFC5289]
-         * 0xC0,0x28  TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384     [RFC5289]
-         * 0xC0,0x29  TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256      [RFC5289]
-         * 0xC0,0x2A  TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384      [RFC5289]
-         * 0xC0,0x2B  TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256   [RFC5289]
-         * 0xC0,0x2C  TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384   [RFC5289]
-         * 0xC0,0x2D  TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256    [RFC5289]
-         * 0xC0,0x2E  TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384    [RFC5289]
-         * 0xC0,0x2F  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256     [RFC5289]
-         * 0xC0,0x30  TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384     [RFC5289]
-         * 0xC0,0x31  TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256      [RFC5289]
-         * 0xC0,0x32  TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384      [RFC5289]
-         * 0xC0,0x33  TLS_ECDHE_PSK_WITH_RC4_128_SHA            [RFC5489]
-         * 0xC0,0x34  TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA       [RFC5489]
-         * 0xC0,0x35  TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA        [RFC5489]
-         * 0xC0,0x36  TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA        [RFC5489]
-         * 0xC0,0x37  TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256     [RFC5489]
-         * 0xC0,0x38  TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384     [RFC5489]
-         * 0xC0,0x39  TLS_ECDHE_PSK_WITH_NULL_SHA               [RFC5489]
-         * 0xC0,0x3A  TLS_ECDHE_PSK_WITH_NULL_SHA256            [RFC5489]
-         * 0xC0,0x3B  TLS_ECDHE_PSK_WITH_NULL_SHA384            [RFC5489]
-         * 0xC0,0x3C-FF Unassigned
-         * 0xC1-FD,*  Unassigned
-         * 0xFE,0x00-FD Unassigned
-         * 0xFE,0xFE-FF Reserved to avoid conflicts with widely
-         *            deployed implementations                  [Pasi_Eronen]
-         * 0xFF,0x00-FF Reserved for Private Use                [RFC5246]
-         */
-
-        add("SSL_NULL_WITH_NULL_NULL",
-                              0x0000,   1, K_NULL,       B_NULL,    F);
-
-        /*
-         * Definition of the CipherSuites that are enabled by default.
-         * They are listed in preference order, most preferred first, using
-         * the following criteria:
-         * 1. Prefer the stronger buld cipher, in the order of AES_256,
-         *    AES_128, RC-4, 3DES-EDE.
-         * 2. Prefer the stronger MAC algorithm, in the order of SHA384,
-         *    SHA256, SHA, MD5.
-         * 3. Prefer the better performance of key exchange and digital
-         *    signature algorithm, in the order of ECDHE-ECDSA, ECDHE-RSA,
-         *    RSA, ECDH-ECDSA, ECDH-RSA, DHE-RSA, DHE-DSS.
-         */
-        int p = DEFAULT_SUITES_PRIORITY * 2;
-
-        // shorten names to fit the following table cleanly.
-        int max = ProtocolVersion.LIMIT_MAX_VALUE;
-        int tls11 = ProtocolVersion.TLS11.v;
-        int tls12 = ProtocolVersion.TLS12.v;
-
-        //  ID           Key Exchange   Cipher     A  obs  suprt  PRF
-        //  ======       ============   =========  =  ===  =====  ========
-        add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
-            0xc024, --p, K_ECDHE_ECDSA, B_AES_256, T, max, tls12, P_SHA384);
-        add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
-            0xc028, --p, K_ECDHE_RSA,   B_AES_256, T, max, tls12, P_SHA384);
-        add("TLS_RSA_WITH_AES_256_CBC_SHA256",
-            0x003d, --p, K_RSA,         B_AES_256, T, max, tls12, P_SHA256);
-        add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",
-            0xc026, --p, K_ECDH_ECDSA,  B_AES_256, T, max, tls12, P_SHA384);
-        add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",
-            0xc02a, --p, K_ECDH_RSA,    B_AES_256, T, max, tls12, P_SHA384);
-        add("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
-            0x006b, --p, K_DHE_RSA,     B_AES_256, T, max, tls12, P_SHA256);
-        add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",
-            0x006a, --p, K_DHE_DSS,     B_AES_256, T, max, tls12, P_SHA256);
-
-        add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
-            0xC00A, --p, K_ECDHE_ECDSA, B_AES_256, T);
-        add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
-            0xC014, --p, K_ECDHE_RSA,   B_AES_256, T);
-        add("TLS_RSA_WITH_AES_256_CBC_SHA",
-            0x0035, --p, K_RSA,         B_AES_256, T);
-        add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
-            0xC005, --p, K_ECDH_ECDSA,  B_AES_256, T);
-        add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
-            0xC00F, --p, K_ECDH_RSA,    B_AES_256, T);
-        add("TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
-            0x0039, --p, K_DHE_RSA,     B_AES_256, T);
-        add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
-            0x0038, --p, K_DHE_DSS,     B_AES_256, T);
-
-        add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
-            0xc023, --p, K_ECDHE_ECDSA, B_AES_128, T, max, tls12, P_SHA256);
-        add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
-            0xc027, --p, K_ECDHE_RSA,   B_AES_128, T, max, tls12, P_SHA256);
-        add("TLS_RSA_WITH_AES_128_CBC_SHA256",
-            0x003c, --p, K_RSA,         B_AES_128, T, max, tls12, P_SHA256);
-        add("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
-            0xc025, --p, K_ECDH_ECDSA,  B_AES_128, T, max, tls12, P_SHA256);
-        add("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",
-            0xc029, --p, K_ECDH_RSA,    B_AES_128, T, max, tls12, P_SHA256);
-        add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
-            0x0067, --p, K_DHE_RSA,     B_AES_128, T, max, tls12, P_SHA256);
-        add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA256",
-            0x0040, --p, K_DHE_DSS,     B_AES_128, T, max, tls12, P_SHA256);
-
-        add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
-            0xC009, --p, K_ECDHE_ECDSA, B_AES_128, T);
-        add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
-            0xC013, --p, K_ECDHE_RSA,   B_AES_128, T);
-        add("TLS_RSA_WITH_AES_128_CBC_SHA",
-            0x002f, --p, K_RSA,         B_AES_128, T);
-        add("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
-            0xC004, --p, K_ECDH_ECDSA,  B_AES_128, T);
-        add("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
-            0xC00E, --p, K_ECDH_RSA,    B_AES_128, T);
-        add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
-            0x0033, --p, K_DHE_RSA,     B_AES_128, T);
-        add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
-            0x0032, --p, K_DHE_DSS,     B_AES_128, T);
-
-        add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
-            0xC007, --p, K_ECDHE_ECDSA, B_RC4_128, N);
-        add("TLS_ECDHE_RSA_WITH_RC4_128_SHA",
-            0xC011, --p, K_ECDHE_RSA,   B_RC4_128, N);
-        add("SSL_RSA_WITH_RC4_128_SHA",
-            0x0005, --p, K_RSA,         B_RC4_128, N);
-        add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
-            0xC002, --p, K_ECDH_ECDSA,  B_RC4_128, N);
-        add("TLS_ECDH_RSA_WITH_RC4_128_SHA",
-            0xC00C, --p, K_ECDH_RSA,    B_RC4_128, N);
-
-        add("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
-            0xC008, --p, K_ECDHE_ECDSA, B_3DES,    T);
-        add("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
-            0xC012, --p, K_ECDHE_RSA,   B_3DES,    T);
-        add("SSL_RSA_WITH_3DES_EDE_CBC_SHA",
-            0x000a, --p, K_RSA,         B_3DES,    T);
-        add("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
-            0xC003, --p, K_ECDH_ECDSA,  B_3DES,    T);
-        add("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
-            0xC00D, --p, K_ECDH_RSA,    B_3DES,    T);
-        add("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
-            0x0016, --p, K_DHE_RSA,     B_3DES,    T);
-        add("SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
-            0x0013, --p, K_DHE_DSS,     B_3DES,    N);
-
-        add("SSL_RSA_WITH_RC4_128_MD5",
-            0x0004, --p, K_RSA,         B_RC4_128, N);
-
-        // Renegotiation protection request Signalling Cipher Suite Value (SCSV)
-        add("TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
-            0x00ff, --p, K_SCSV,        B_NULL,    T);
-
-        /*
-         * Definition of the CipherSuites that are supported but not enabled
-         * by default.
-         * They are listed in preference order, preferred first, using the
-         * following criteria:
-         * 1. CipherSuites for KRB5 need additional KRB5 service
-         *    configuration, and these suites are not common in practice,
-         *    so we put KRB5 based cipher suites at the end of the supported
-         *    list.
-         * 2. If a cipher suite has been obsoleted, we put it at the end of
-         *    the list.
-         * 3. Prefer the stronger bulk cipher, in the order of AES_256,
-         *    AES_128, RC-4, 3DES-EDE, DES, RC4_40, DES40, NULL.
-         * 4. Prefer the stronger MAC algorithm, in the order of SHA384,
-         *    SHA256, SHA, MD5.
-         * 5. Prefer the better performance of key exchange and digital
-         *    signature algorithm, in the order of ECDHE-ECDSA, ECDHE-RSA,
-         *    RSA, ECDH-ECDSA, ECDH-RSA, DHE-RSA, DHE-DSS, anonymous.
-         */
-        p = DEFAULT_SUITES_PRIORITY;
-
-        add("TLS_DH_anon_WITH_AES_256_CBC_SHA256",
-            0x006d, --p, K_DH_ANON,     B_AES_256, N, max, tls12, P_SHA256);
-        add("TLS_ECDH_anon_WITH_AES_256_CBC_SHA",
-            0xC019, --p, K_ECDH_ANON,   B_AES_256, T);
-        add("TLS_DH_anon_WITH_AES_256_CBC_SHA",
-            0x003a, --p, K_DH_ANON,     B_AES_256, N);
-
-        add("TLS_DH_anon_WITH_AES_128_CBC_SHA256",
-            0x006c, --p, K_DH_ANON,     B_AES_128, N, max, tls12, P_SHA256);
-        add("TLS_ECDH_anon_WITH_AES_128_CBC_SHA",
-            0xC018, --p, K_ECDH_ANON,   B_AES_128, T);
-        add("TLS_DH_anon_WITH_AES_128_CBC_SHA",
-            0x0034, --p, K_DH_ANON,     B_AES_128, N);
-
-        add("TLS_ECDH_anon_WITH_RC4_128_SHA",
-            0xC016, --p, K_ECDH_ANON,   B_RC4_128, N);
-        add("SSL_DH_anon_WITH_RC4_128_MD5",
-            0x0018, --p, K_DH_ANON,     B_RC4_128, N);
-
-        add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
-            0xC017, --p, K_ECDH_ANON,   B_3DES,    T);
-        add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",
-            0x001b, --p, K_DH_ANON,     B_3DES,    N);
-
-        add("TLS_RSA_WITH_NULL_SHA256",
-            0x003b, --p, K_RSA,         B_NULL,    N, max, tls12, P_SHA256);
-        add("TLS_ECDHE_ECDSA_WITH_NULL_SHA",
-            0xC006, --p, K_ECDHE_ECDSA, B_NULL,    N);
-        add("TLS_ECDHE_RSA_WITH_NULL_SHA",
-            0xC010, --p, K_ECDHE_RSA,   B_NULL,    N);
-        add("SSL_RSA_WITH_NULL_SHA",
-            0x0002, --p, K_RSA,         B_NULL,    N);
-        add("TLS_ECDH_ECDSA_WITH_NULL_SHA",
-            0xC001, --p, K_ECDH_ECDSA,  B_NULL,    N);
-        add("TLS_ECDH_RSA_WITH_NULL_SHA",
-            0xC00B, --p, K_ECDH_RSA,    B_NULL,    N);
-        add("TLS_ECDH_anon_WITH_NULL_SHA",
-            0xC015, --p, K_ECDH_ANON,   B_NULL,    N);
-        add("SSL_RSA_WITH_NULL_MD5",
-            0x0001, --p, K_RSA,         B_NULL,    N);
-
-        // weak cipher suites obsoleted in TLS 1.2
-        add("SSL_RSA_WITH_DES_CBC_SHA",
-            0x0009, --p, K_RSA,         B_DES,     N, tls12);
-        add("SSL_DHE_RSA_WITH_DES_CBC_SHA",
-            0x0015, --p, K_DHE_RSA,     B_DES,     N, tls12);
-        add("SSL_DHE_DSS_WITH_DES_CBC_SHA",
-            0x0012, --p, K_DHE_DSS,     B_DES,     N, tls12);
-        add("SSL_DH_anon_WITH_DES_CBC_SHA",
-            0x001a, --p, K_DH_ANON,     B_DES,     N, tls12);
-
-        // weak cipher suites obsoleted in TLS 1.1
-        add("SSL_RSA_EXPORT_WITH_RC4_40_MD5",
-            0x0003, --p, K_RSA_EXPORT,  B_RC4_40,  N, tls11);
-        add("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
-            0x0017, --p, K_DH_ANON,     B_RC4_40,  N, tls11);
-
-        add("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
-            0x0008, --p, K_RSA_EXPORT,  B_DES_40,  N, tls11);
-        add("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
-            0x0014, --p, K_DHE_RSA,     B_DES_40,  N, tls11);
-        add("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
-            0x0011, --p, K_DHE_DSS,     B_DES_40,  N, tls11);
-        add("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
-            0x0019, --p, K_DH_ANON,     B_DES_40,  N, tls11);
-
-        // Supported Kerberos ciphersuites from RFC2712
-        add("TLS_KRB5_WITH_RC4_128_SHA",
-            0x0020, --p, K_KRB5,        B_RC4_128, N);
-        add("TLS_KRB5_WITH_RC4_128_MD5",
-            0x0024, --p, K_KRB5,        B_RC4_128, N);
-        add("TLS_KRB5_WITH_3DES_EDE_CBC_SHA",
-            0x001f, --p, K_KRB5,        B_3DES,    N);
-        add("TLS_KRB5_WITH_3DES_EDE_CBC_MD5",
-            0x0023, --p, K_KRB5,        B_3DES,    N);
-        add("TLS_KRB5_WITH_DES_CBC_SHA",
-            0x001e, --p, K_KRB5,        B_DES,     N, tls12);
-        add("TLS_KRB5_WITH_DES_CBC_MD5",
-            0x0022, --p, K_KRB5,        B_DES,     N, tls12);
-        add("TLS_KRB5_EXPORT_WITH_RC4_40_SHA",
-            0x0028, --p, K_KRB5_EXPORT, B_RC4_40,  N, tls11);
-        add("TLS_KRB5_EXPORT_WITH_RC4_40_MD5",
-            0x002b, --p, K_KRB5_EXPORT, B_RC4_40,  N, tls11);
-        add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA",
-            0x0026, --p, K_KRB5_EXPORT, B_DES_40,  N, tls11);
-        add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5",
-            0x0029, --p, K_KRB5_EXPORT, B_DES_40,  N, tls11);
-
-        /*
-         * Other values from the TLS Cipher Suite Registry, as of August 2010.
-         *
-         * http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
-         *
-         * Range      Registration Procedures   Notes
-         * 000-191    Standards Action          Refers to value of first byte
-         * 192-254    Specification Required    Refers to value of first byte
-         * 255        Reserved for Private Use  Refers to value of first byte
-         */
-
-        // Register the names of a few additional CipherSuites.
-        // Makes them show up as names instead of numbers in
-        // the debug output.
-
-        // remaining unsupported ciphersuites defined in RFC2246.
-        add("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5",          0x0006);
-        add("SSL_RSA_WITH_IDEA_CBC_SHA",                   0x0007);
-        add("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA",        0x000b);
-        add("SSL_DH_DSS_WITH_DES_CBC_SHA",                 0x000c);
-        add("SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA",            0x000d);
-        add("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA",        0x000e);
-        add("SSL_DH_RSA_WITH_DES_CBC_SHA",                 0x000f);
-        add("SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA",            0x0010);
-
-        // SSL 3.0 Fortezza ciphersuites
-        add("SSL_FORTEZZA_DMS_WITH_NULL_SHA",              0x001c);
-        add("SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA",      0x001d);
-
-        // 1024/56 bit exportable ciphersuites from expired internet draft
-        add("SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA",         0x0062);
-        add("SSL_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA",     0x0063);
-        add("SSL_RSA_EXPORT1024_WITH_RC4_56_SHA",          0x0064);
-        add("SSL_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA",      0x0065);
-        add("SSL_DHE_DSS_WITH_RC4_128_SHA",                0x0066);
-
-        // Netscape old and new SSL 3.0 FIPS ciphersuites
-        // see http://www.mozilla.org/projects/security/pki/nss/ssl/fips-ssl-ciphersuites.html
-        add("NETSCAPE_RSA_FIPS_WITH_3DES_EDE_CBC_SHA",     0xffe0);
-        add("NETSCAPE_RSA_FIPS_WITH_DES_CBC_SHA",          0xffe1);
-        add("SSL_RSA_FIPS_WITH_DES_CBC_SHA",               0xfefe);
-        add("SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA",          0xfeff);
-
-        // Unsupported Kerberos cipher suites from RFC 2712
-        add("TLS_KRB5_WITH_IDEA_CBC_SHA",                  0x0021);
-        add("TLS_KRB5_WITH_IDEA_CBC_MD5",                  0x0025);
-        add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA",         0x0027);
-        add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5",         0x002a);
-
-        // Unsupported cipher suites from RFC 4162
-        add("TLS_RSA_WITH_SEED_CBC_SHA",                   0x0096);
-        add("TLS_DH_DSS_WITH_SEED_CBC_SHA",                0x0097);
-        add("TLS_DH_RSA_WITH_SEED_CBC_SHA",                0x0098);
-        add("TLS_DHE_DSS_WITH_SEED_CBC_SHA",               0x0099);
-        add("TLS_DHE_RSA_WITH_SEED_CBC_SHA",               0x009a);
-        add("TLS_DH_anon_WITH_SEED_CBC_SHA",               0x009b);
-
-        // Unsupported cipher suites from RFC 4279
-        add("TLS_PSK_WITH_RC4_128_SHA",                    0x008a);
-        add("TLS_PSK_WITH_3DES_EDE_CBC_SHA",               0x008b);
-        add("TLS_PSK_WITH_AES_128_CBC_SHA",                0x008c);
-        add("TLS_PSK_WITH_AES_256_CBC_SHA",                0x008d);
-        add("TLS_DHE_PSK_WITH_RC4_128_SHA",                0x008e);
-        add("TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA",           0x008f);
-        add("TLS_DHE_PSK_WITH_AES_128_CBC_SHA",            0x0090);
-        add("TLS_DHE_PSK_WITH_AES_256_CBC_SHA",            0x0091);
-        add("TLS_RSA_PSK_WITH_RC4_128_SHA",                0x0092);
-        add("TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA",           0x0093);
-        add("TLS_RSA_PSK_WITH_AES_128_CBC_SHA",            0x0094);
-        add("TLS_RSA_PSK_WITH_AES_256_CBC_SHA",            0x0095);
-
-        // Unsupported cipher suites from RFC 4785
-        add("TLS_PSK_WITH_NULL_SHA",                       0x002c);
-        add("TLS_DHE_PSK_WITH_NULL_SHA",                   0x002d);
-        add("TLS_RSA_PSK_WITH_NULL_SHA",                   0x002e);
-
-        // Unsupported cipher suites from RFC 5246
-        add("TLS_DH_DSS_WITH_AES_128_CBC_SHA",             0x0030);
-        add("TLS_DH_RSA_WITH_AES_128_CBC_SHA",             0x0031);
-        add("TLS_DH_DSS_WITH_AES_256_CBC_SHA",             0x0036);
-        add("TLS_DH_RSA_WITH_AES_256_CBC_SHA",             0x0037);
-        add("TLS_DH_DSS_WITH_AES_128_CBC_SHA256",          0x003e);
-        add("TLS_DH_RSA_WITH_AES_128_CBC_SHA256",          0x003f);
-        add("TLS_DH_DSS_WITH_AES_256_CBC_SHA256",          0x0068);
-        add("TLS_DH_RSA_WITH_AES_256_CBC_SHA256",          0x0069);
-
-        // Unsupported cipher suites from RFC 5288
-        add("TLS_RSA_WITH_AES_128_GCM_SHA256",             0x009c);
-        add("TLS_RSA_WITH_AES_256_GCM_SHA384",             0x009d);
-        add("TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",         0x009e);
-        add("TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",         0x009f);
-        add("TLS_DH_RSA_WITH_AES_128_GCM_SHA256",          0x00a0);
-        add("TLS_DH_RSA_WITH_AES_256_GCM_SHA384",          0x00a1);
-        add("TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",         0x00a2);
-        add("TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",         0x00a3);
-        add("TLS_DH_DSS_WITH_AES_128_GCM_SHA256",          0x00a4);
-        add("TLS_DH_DSS_WITH_AES_256_GCM_SHA384",          0x00a5);
-        add("TLS_DH_anon_WITH_AES_128_GCM_SHA256",         0x00a6);
-        add("TLS_DH_anon_WITH_AES_256_GCM_SHA384",         0x00a7);
-
-        // Unsupported cipher suites from RFC 5487
-        add("TLS_PSK_WITH_AES_128_GCM_SHA256",             0x00a8);
-        add("TLS_PSK_WITH_AES_256_GCM_SHA384",             0x00a9);
-        add("TLS_DHE_PSK_WITH_AES_128_GCM_SHA256",         0x00aa);
-        add("TLS_DHE_PSK_WITH_AES_256_GCM_SHA384",         0x00ab);
-        add("TLS_RSA_PSK_WITH_AES_128_GCM_SHA256",         0x00ac);
-        add("TLS_RSA_PSK_WITH_AES_256_GCM_SHA384",         0x00ad);
-        add("TLS_PSK_WITH_AES_128_CBC_SHA256",             0x00ae);
-        add("TLS_PSK_WITH_AES_256_CBC_SHA384",             0x00af);
-        add("TLS_PSK_WITH_NULL_SHA256",                    0x00b0);
-        add("TLS_PSK_WITH_NULL_SHA384",                    0x00b1);
-        add("TLS_DHE_PSK_WITH_AES_128_CBC_SHA256",         0x00b2);
-        add("TLS_DHE_PSK_WITH_AES_256_CBC_SHA384",         0x00b3);
-        add("TLS_DHE_PSK_WITH_NULL_SHA256",                0x00b4);
-        add("TLS_DHE_PSK_WITH_NULL_SHA384",                0x00b5);
-        add("TLS_RSA_PSK_WITH_AES_128_CBC_SHA256",         0x00b6);
-        add("TLS_RSA_PSK_WITH_AES_256_CBC_SHA384",         0x00b7);
-        add("TLS_RSA_PSK_WITH_NULL_SHA256",                0x00b8);
-        add("TLS_RSA_PSK_WITH_NULL_SHA384",                0x00b9);
-
-        // Unsupported cipher suites from RFC 5932
-        add("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA",           0x0041);
-        add("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA",        0x0042);
-        add("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA",        0x0043);
-        add("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA",       0x0044);
-        add("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA",       0x0045);
-        add("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA",       0x0046);
-        add("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA",           0x0084);
-        add("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA",        0x0085);
-        add("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA",        0x0086);
-        add("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA",       0x0087);
-        add("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA",       0x0088);
-        add("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA",       0x0089);
-        add("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256",        0x00ba);
-        add("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256",     0x00bb);
-        add("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256",     0x00bc);
-        add("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256",    0x00bd);
-        add("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256",    0x00be);
-        add("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256",    0x00bf);
-        add("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256",        0x00c0);
-        add("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256",     0x00c1);
-        add("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256",     0x00c2);
-        add("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256",    0x00c3);
-        add("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256",    0x00c4);
-        add("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256",    0x00c5);
-
-        // Unsupported cipher suites from RFC 5054
-        add("TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA",           0xc01a);
-        add("TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA",       0xc01b);
-        add("TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA",       0xc01c);
-        add("TLS_SRP_SHA_WITH_AES_128_CBC_SHA",            0xc01d);
-        add("TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA",        0xc01e);
-        add("TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA",        0xc01f);
-        add("TLS_SRP_SHA_WITH_AES_256_CBC_SHA",            0xc020);
-        add("TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA",        0xc021);
-        add("TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA",        0xc022);
-
-        // Unsupported cipher suites from RFC 5289
-        add("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",     0xc02b);
-        add("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",     0xc02c);
-        add("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",      0xc02d);
-        add("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",      0xc02e);
-        add("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",       0xc02f);
-        add("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",       0xc030);
-        add("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",        0xc031);
-        add("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",        0xc032);
-
-        // Unsupported cipher suites from RFC 5489
-        add("TLS_ECDHE_PSK_WITH_RC4_128_SHA",              0xc033);
-        add("TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA",         0xc034);
-        add("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",          0xc035);
-        add("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA",          0xc036);
-        add("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256",       0xc037);
-        add("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384",       0xc038);
-        add("TLS_ECDHE_PSK_WITH_NULL_SHA",                 0xc039);
-        add("TLS_ECDHE_PSK_WITH_NULL_SHA256",              0xc03a);
-        add("TLS_ECDHE_PSK_WITH_NULL_SHA384",              0xc03b);
-    }
-
-    // ciphersuite SSL_NULL_WITH_NULL_NULL
-    final static CipherSuite C_NULL = CipherSuite.valueOf(0, 0);
-
-    // ciphersuite TLS_EMPTY_RENEGOTIATION_INFO_SCSV
-    final static CipherSuite C_SCSV = CipherSuite.valueOf(0x00, 0xff);
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/CipherSuiteList.java b/ojluni/src/main/java/sun/security/ssl/CipherSuiteList.java
deleted file mode 100755
index bf69b35..0000000
--- a/ojluni/src/main/java/sun/security/ssl/CipherSuiteList.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.util.*;
-
-import javax.net.ssl.SSLException;
-
-/**
- * A list of CipherSuites. Also maintains the lists of supported and
- * default ciphersuites and supports I/O from handshake streams.
- *
- * Instances of this class are immutable.
- *
- */
-final class CipherSuiteList {
-
-    private final Collection<CipherSuite> cipherSuites;
-    private String[] suiteNames;
-
-    // flag indicating whether this list contains any ECC ciphersuites.
-    // null if not yet checked.
-    private volatile Boolean containsEC;
-
-    // for use by buildAvailableCache() and
-    // Handshaker.getKickstartMessage() only
-    CipherSuiteList(Collection<CipherSuite> cipherSuites) {
-        this.cipherSuites = cipherSuites;
-    }
-
-    /**
-     * Create a CipherSuiteList with a single element.
-     */
-    CipherSuiteList(CipherSuite suite) {
-        cipherSuites = new ArrayList<CipherSuite>(1);
-        cipherSuites.add(suite);
-    }
-
-    /**
-     * Construct a CipherSuiteList from a array of names. We don't bother
-     * to eliminate duplicates.
-     *
-     * @exception IllegalArgumentException if the array or any of its elements
-     * is null or if the ciphersuite name is unrecognized or unsupported
-     * using currently installed providers.
-     */
-    CipherSuiteList(String[] names) {
-        if (names == null) {
-            throw new IllegalArgumentException("CipherSuites may not be null");
-        }
-        cipherSuites = new ArrayList<CipherSuite>(names.length);
-        // refresh available cache once if a CipherSuite is not available
-        // (maybe new JCE providers have been installed)
-        boolean refreshed = false;
-        for (int i = 0; i < names.length; i++) {
-            String suiteName = names[i];
-            CipherSuite suite = CipherSuite.valueOf(suiteName);
-            if (suite.isAvailable() == false) {
-                if (refreshed == false) {
-                    // clear the cache so that the isAvailable() call below
-                    // does a full check
-                    clearAvailableCache();
-                    refreshed = true;
-                }
-                // still missing?
-                if (suite.isAvailable() == false) {
-                    throw new IllegalArgumentException("Cannot support "
-                        + suiteName + " with currently installed providers");
-                }
-            }
-            cipherSuites.add(suite);
-        }
-    }
-
-    /**
-     * Read a CipherSuiteList from a HandshakeInStream in V3 ClientHello
-     * format. Does not check if the listed ciphersuites are known or
-     * supported.
-     */
-    CipherSuiteList(HandshakeInStream in) throws IOException {
-        byte[] bytes = in.getBytes16();
-        if ((bytes.length & 1) != 0) {
-            throw new SSLException("Invalid ClientHello message");
-        }
-        cipherSuites = new ArrayList<CipherSuite>(bytes.length >> 1);
-        for (int i = 0; i < bytes.length; i += 2) {
-            cipherSuites.add(CipherSuite.valueOf(bytes[i], bytes[i+1]));
-        }
-    }
-
-    /**
-     * Return whether this list contains the given CipherSuite.
-     */
-    boolean contains(CipherSuite suite) {
-        return cipherSuites.contains(suite);
-    }
-
-    // Return whether this list contains any ECC ciphersuites
-    boolean containsEC() {
-        if (containsEC == null) {
-            for (CipherSuite c : cipherSuites) {
-                switch (c.keyExchange) {
-                case K_ECDH_ECDSA:
-                case K_ECDH_RSA:
-                case K_ECDHE_ECDSA:
-                case K_ECDHE_RSA:
-                case K_ECDH_ANON:
-                    containsEC = true;
-                    return true;
-                default:
-                    break;
-                }
-            }
-            containsEC = false;
-        }
-        return containsEC;
-    }
-
-    /**
-     * Return an Iterator for the CipherSuites in this list.
-     */
-    Iterator<CipherSuite> iterator() {
-        return cipherSuites.iterator();
-    }
-
-    /**
-     * Return a reference to the internal Collection of CipherSuites.
-     * The Collection MUST NOT be modified.
-     */
-    Collection<CipherSuite> collection() {
-        return cipherSuites;
-    }
-
-    /**
-     * Return the number of CipherSuites in this list.
-     */
-    int size() {
-        return cipherSuites.size();
-    }
-
-    /**
-     * Return an array with the names of the CipherSuites in this list.
-     */
-    synchronized String[] toStringArray() {
-        if (suiteNames == null) {
-            suiteNames = new String[cipherSuites.size()];
-            int i = 0;
-            for (CipherSuite c : cipherSuites) {
-                suiteNames[i++] = c.name;
-            }
-        }
-        return suiteNames.clone();
-    }
-
-    public String toString() {
-        return cipherSuites.toString();
-    }
-
-    /**
-     * Write this list to an HandshakeOutStream in V3 ClientHello format.
-     */
-    void send(HandshakeOutStream s) throws IOException {
-        byte[] suiteBytes = new byte[cipherSuites.size() * 2];
-        int i = 0;
-        for (CipherSuite c : cipherSuites) {
-            suiteBytes[i] = (byte)(c.id >> 8);
-            suiteBytes[i+1] = (byte)c.id;
-            i += 2;
-        }
-        s.putBytes16(suiteBytes);
-    }
-
-    /**
-     * Clear cache of available ciphersuites. If we support all ciphers
-     * internally, there is no need to clear the cache and calling this
-     * method has no effect.
-     */
-    static synchronized void clearAvailableCache() {
-        if (CipherSuite.DYNAMIC_AVAILABILITY) {
-            CipherSuite.BulkCipher.clearAvailableCache();
-            JsseJce.clearEcAvailable();
-        }
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/ClientHandshaker.java b/ojluni/src/main/java/sun/security/ssl/ClientHandshaker.java
deleted file mode 100755
index 0c1022b..0000000
--- a/ojluni/src/main/java/sun/security/ssl/ClientHandshaker.java
+++ /dev/null
@@ -1,1345 +0,0 @@
-/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.math.BigInteger;
-import java.security.*;
-import java.util.*;
-
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.ECParameterSpec;
-
-import java.security.cert.X509Certificate;
-import java.security.cert.CertificateException;
-
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-
-import javax.net.ssl.*;
-
-import javax.security.auth.Subject;
-
-import sun.security.ssl.HandshakeMessage.*;
-import sun.security.ssl.CipherSuite.*;
-import static sun.security.ssl.CipherSuite.KeyExchange.*;
-
-import sun.net.util.IPAddressUtil;
-
-/**
- * ClientHandshaker does the protocol handshaking from the point
- * of view of a client.  It is driven asychronously by handshake messages
- * as delivered by the parent Handshaker class, and also uses
- * common functionality (e.g. key generation) that is provided there.
- *
- * @author David Brownell
- */
-final class ClientHandshaker extends Handshaker {
-
-    // the server's public key from its certificate.
-    private PublicKey serverKey;
-
-    // the server's ephemeral public key from the server key exchange message
-    // for ECDHE/ECDH_anon and RSA_EXPORT.
-    private PublicKey ephemeralServerKey;
-
-    // server's ephemeral public value for DHE/DH_anon key exchanges
-    private BigInteger          serverDH;
-
-    private DHCrypt             dh;
-
-    private ECDHCrypt ecdh;
-
-    private CertificateRequest  certRequest;
-
-    private boolean serverKeyExchangeReceived;
-
-    /*
-     * The RSA PreMasterSecret needs to know the version of
-     * ClientHello that was used on this handshake.  This represents
-     * the "max version" this client is supporting.  In the
-     * case of an initial handshake, it's the max version enabled,
-     * but in the case of a resumption attempt, it's the version
-     * of the session we're trying to resume.
-     */
-    private ProtocolVersion maxProtocolVersion;
-
-    // To switch off the SNI extension.
-    private final static boolean enableSNIExtension =
-            Debug.getBooleanProperty("jsse.enableSNIExtension", true);
-
-    /*
-     * Constructors
-     */
-    ClientHandshaker(SSLSocketImpl socket, SSLContextImpl context,
-            ProtocolList enabledProtocols,
-            ProtocolVersion activeProtocolVersion,
-            boolean isInitialHandshake, boolean secureRenegotiation,
-            byte[] clientVerifyData, byte[] serverVerifyData) {
-
-        super(socket, context, enabledProtocols, true, true,
-            activeProtocolVersion, isInitialHandshake, secureRenegotiation,
-            clientVerifyData, serverVerifyData);
-    }
-
-    ClientHandshaker(SSLEngineImpl engine, SSLContextImpl context,
-            ProtocolList enabledProtocols,
-            ProtocolVersion activeProtocolVersion,
-            boolean isInitialHandshake, boolean secureRenegotiation,
-            byte[] clientVerifyData, byte[] serverVerifyData) {
-
-        super(engine, context, enabledProtocols, true, true,
-            activeProtocolVersion, isInitialHandshake, secureRenegotiation,
-            clientVerifyData, serverVerifyData);
-    }
-
-    /*
-     * This routine handles all the client side handshake messages, one at
-     * a time.  Given the message type (and in some cases the pending cipher
-     * spec) it parses the type-specific message.  Then it calls a function
-     * that handles that specific message.
-     *
-     * It updates the state machine (need to verify it) as each message
-     * is processed, and writes responses as needed using the connection
-     * in the constructor.
-     */
-    void processMessage(byte type, int messageLen) throws IOException {
-        if (state >= type
-                && (type != HandshakeMessage.ht_hello_request)) {
-            throw new SSLProtocolException(
-                    "Handshake message sequence violation, " + type);
-        }
-
-        switch (type) {
-        case HandshakeMessage.ht_hello_request:
-            this.serverHelloRequest(new HelloRequest(input));
-            break;
-
-        case HandshakeMessage.ht_server_hello:
-            this.serverHello(new ServerHello(input, messageLen));
-            break;
-
-        case HandshakeMessage.ht_certificate:
-            if (keyExchange == K_DH_ANON || keyExchange == K_ECDH_ANON
-                    || keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
-                fatalSE(Alerts.alert_unexpected_message,
-                    "unexpected server cert chain");
-                // NOTREACHED
-            }
-            this.serverCertificate(new CertificateMsg(input));
-            serverKey =
-                session.getPeerCertificates()[0].getPublicKey();
-            break;
-
-        case HandshakeMessage.ht_server_key_exchange:
-            serverKeyExchangeReceived = true;
-            switch (keyExchange) {
-            case K_RSA_EXPORT:
-                /**
-                 * The server key exchange message is sent by the server only
-                 * when the server certificate message does not contain the
-                 * proper amount of data to allow the client to exchange a
-                 * premaster secret, such as when RSA_EXPORT is used and the
-                 * public key in the server certificate is longer than 512 bits.
-                 */
-                if (serverKey == null) {
-                    throw new SSLProtocolException
-                        ("Server did not send certificate message");
-                }
-
-                if (!(serverKey instanceof RSAPublicKey)) {
-                    throw new SSLProtocolException("Protocol violation:" +
-                        " the certificate type must be appropriate for the" +
-                        " selected cipher suite's key exchange algorithm");
-                }
-
-                if (JsseJce.getRSAKeyLength(serverKey) <= 512) {
-                    throw new SSLProtocolException("Protocol violation:" +
-                        " server sent a server key exchange message for" +
-                        " key exchange " + keyExchange +
-                        " when the public key in the server certificate" +
-                        " is less than or equal to 512 bits in length");
-                }
-
-                try {
-                    this.serverKeyExchange(new RSA_ServerKeyExchange(input));
-                } catch (GeneralSecurityException e) {
-                    throwSSLException("Server key", e);
-                }
-                break;
-            case K_DH_ANON:
-                try {
-                    this.serverKeyExchange(new DH_ServerKeyExchange(
-                                                input, protocolVersion));
-                } catch (GeneralSecurityException e) {
-                    throwSSLException("Server key", e);
-                }
-                break;
-            case K_DHE_DSS:
-            case K_DHE_RSA:
-                try {
-                    this.serverKeyExchange(new DH_ServerKeyExchange(
-                        input, serverKey,
-                        clnt_random.random_bytes, svr_random.random_bytes,
-                        messageLen,
-                        localSupportedSignAlgs, protocolVersion));
-                } catch (GeneralSecurityException e) {
-                    throwSSLException("Server key", e);
-                }
-                break;
-            case K_ECDHE_ECDSA:
-            case K_ECDHE_RSA:
-            case K_ECDH_ANON:
-                try {
-                    this.serverKeyExchange(new ECDH_ServerKeyExchange
-                        (input, serverKey, clnt_random.random_bytes,
-                        svr_random.random_bytes,
-                        localSupportedSignAlgs, protocolVersion));
-                } catch (GeneralSecurityException e) {
-                    throwSSLException("Server key", e);
-                }
-                break;
-            case K_RSA:
-            case K_DH_RSA:
-            case K_DH_DSS:
-            case K_ECDH_ECDSA:
-            case K_ECDH_RSA:
-                throw new SSLProtocolException(
-                    "Protocol violation: server sent a server key exchange"
-                    + "message for key exchange " + keyExchange);
-            case K_KRB5:
-            case K_KRB5_EXPORT:
-                throw new SSLProtocolException(
-                    "unexpected receipt of server key exchange algorithm");
-            default:
-                throw new SSLProtocolException(
-                    "unsupported key exchange algorithm = "
-                    + keyExchange);
-            }
-            break;
-
-        case HandshakeMessage.ht_certificate_request:
-            // save for later, it's handled by serverHelloDone
-            if ((keyExchange == K_DH_ANON) || (keyExchange == K_ECDH_ANON)) {
-                throw new SSLHandshakeException(
-                    "Client authentication requested for "+
-                    "anonymous cipher suite.");
-            } else if (keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
-                throw new SSLHandshakeException(
-                    "Client certificate requested for "+
-                    "kerberos cipher suite.");
-            }
-            certRequest = new CertificateRequest(input, protocolVersion);
-            if (debug != null && Debug.isOn("handshake")) {
-                certRequest.print(System.out);
-            }
-
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                Collection<SignatureAndHashAlgorithm> peerSignAlgs =
-                                        certRequest.getSignAlgorithms();
-                if (peerSignAlgs == null || peerSignAlgs.isEmpty()) {
-                    throw new SSLHandshakeException(
-                        "No peer supported signature algorithms");
-                }
-
-                Collection<SignatureAndHashAlgorithm> supportedPeerSignAlgs =
-                    SignatureAndHashAlgorithm.getSupportedAlgorithms(
-                                                            peerSignAlgs);
-                if (supportedPeerSignAlgs.isEmpty()) {
-                    throw new SSLHandshakeException(
-                        "No supported signature and hash algorithm in common");
-                }
-
-                setPeerSupportedSignAlgs(supportedPeerSignAlgs);
-                session.setPeerSupportedSignatureAlgorithms(
-                                                supportedPeerSignAlgs);
-            }
-
-            break;
-
-        case HandshakeMessage.ht_server_hello_done:
-            this.serverHelloDone(new ServerHelloDone(input));
-            break;
-
-        case HandshakeMessage.ht_finished:
-            this.serverFinished(
-                new Finished(protocolVersion, input, cipherSuite));
-            break;
-
-        default:
-            throw new SSLProtocolException(
-                "Illegal client handshake msg, " + type);
-        }
-
-        //
-        // Move state machine forward if the message handling
-        // code didn't already do so
-        //
-        if (state < type) {
-            state = type;
-        }
-    }
-
-    /*
-     * Used by the server to kickstart negotiations -- this requests a
-     * "client hello" to renegotiate current cipher specs (e.g. maybe lots
-     * of data has been encrypted with the same keys, or the server needs
-     * the client to present a certificate).
-     */
-    private void serverHelloRequest(HelloRequest mesg) throws IOException {
-        if (debug != null && Debug.isOn("handshake")) {
-            mesg.print(System.out);
-        }
-
-        //
-        // Could be (e.g. at connection setup) that we already
-        // sent the "client hello" but the server's not seen it.
-        //
-        if (state < HandshakeMessage.ht_client_hello) {
-            if (!secureRenegotiation && !allowUnsafeRenegotiation) {
-                // renegotiation is not allowed.
-                if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) {
-                    // response with a no_renegotiation warning,
-                    warningSE(Alerts.alert_no_renegotiation);
-
-                    // invalidate the handshake so that the caller can
-                    // dispose this object.
-                    invalidated = true;
-
-                    // If there is still unread block in the handshake
-                    // input stream, it would be truncated with the disposal
-                    // and the next handshake message will become incomplete.
-                    //
-                    // However, according to SSL/TLS specifications, no more
-                    // handshake message should immediately follow ClientHello
-                    // or HelloRequest. So just let it be.
-                } else {
-                    // For SSLv3, send the handshake_failure fatal error.
-                    // Note that SSLv3 does not define a no_renegotiation
-                    // alert like TLSv1. However we cannot ignore the message
-                    // simply, otherwise the other side was waiting for a
-                    // response that would never come.
-                    fatalSE(Alerts.alert_handshake_failure,
-                        "Renegotiation is not allowed");
-                }
-            } else {
-                if (!secureRenegotiation) {
-                    if (debug != null && Debug.isOn("handshake")) {
-                        System.out.println(
-                            "Warning: continue with insecure renegotiation");
-                    }
-                }
-                kickstart();
-            }
-        }
-    }
-
-
-    /*
-     * Server chooses session parameters given options created by the
-     * client -- basically, cipher options, session id, and someday a
-     * set of compression options.
-     *
-     * There are two branches of the state machine, decided by the
-     * details of this message.  One is the "fast" handshake, where we
-     * can resume the pre-existing session we asked resume.  The other
-     * is a more expensive "full" handshake, with key exchange and
-     * probably authentication getting done.
-     */
-    private void serverHello(ServerHello mesg) throws IOException {
-        serverKeyExchangeReceived = false;
-        if (debug != null && Debug.isOn("handshake")) {
-            mesg.print(System.out);
-        }
-
-        // check if the server selected protocol version is OK for us
-        ProtocolVersion mesgVersion = mesg.protocolVersion;
-        if (!isNegotiable(mesgVersion)) {
-            throw new SSLHandshakeException(
-                "Server chose " + mesgVersion +
-                ", but that protocol version is not enabled or not supported " +
-                "by the client.");
-        }
-
-        handshakeHash.protocolDetermined(mesgVersion);
-
-        // Set protocolVersion and propagate to SSLSocket and the
-        // Handshake streams
-        setVersion(mesgVersion);
-
-        // check the "renegotiation_info" extension
-        RenegotiationInfoExtension serverHelloRI = (RenegotiationInfoExtension)
-                    mesg.extensions.get(ExtensionType.EXT_RENEGOTIATION_INFO);
-        if (serverHelloRI != null) {
-            if (isInitialHandshake) {
-                // verify the length of the "renegotiated_connection" field
-                if (!serverHelloRI.isEmpty()) {
-                    // abort the handshake with a fatal handshake_failure alert
-                    fatalSE(Alerts.alert_handshake_failure,
-                        "The renegotiation_info field is not empty");
-                }
-
-                secureRenegotiation = true;
-            } else {
-                // For a legacy renegotiation, the client MUST verify that
-                // it does not contain the "renegotiation_info" extension.
-                if (!secureRenegotiation) {
-                    fatalSE(Alerts.alert_handshake_failure,
-                        "Unexpected renegotiation indication extension");
-                }
-
-                // verify the client_verify_data and server_verify_data values
-                byte[] verifyData =
-                    new byte[clientVerifyData.length + serverVerifyData.length];
-                System.arraycopy(clientVerifyData, 0, verifyData,
-                        0, clientVerifyData.length);
-                System.arraycopy(serverVerifyData, 0, verifyData,
-                        clientVerifyData.length, serverVerifyData.length);
-                if (!Arrays.equals(verifyData,
-                                serverHelloRI.getRenegotiatedConnection())) {
-                    fatalSE(Alerts.alert_handshake_failure,
-                        "Incorrect verify data in ServerHello " +
-                        "renegotiation_info message");
-                }
-            }
-        } else {
-            // no renegotiation indication extension
-            if (isInitialHandshake) {
-                if (!allowLegacyHelloMessages) {
-                    // abort the handshake with a fatal handshake_failure alert
-                    fatalSE(Alerts.alert_handshake_failure,
-                        "Failed to negotiate the use of secure renegotiation");
-                }
-
-                secureRenegotiation = false;
-                if (debug != null && Debug.isOn("handshake")) {
-                    System.out.println("Warning: No renegotiation " +
-                                    "indication extension in ServerHello");
-                }
-            } else {
-                // For a secure renegotiation, the client must abort the
-                // handshake if no "renegotiation_info" extension is present.
-                if (secureRenegotiation) {
-                    fatalSE(Alerts.alert_handshake_failure,
-                        "No renegotiation indication extension");
-                }
-
-                // we have already allowed unsafe renegotation before request
-                // the renegotiation.
-            }
-        }
-
-        //
-        // Save server nonce, we always use it to compute connection
-        // keys and it's also used to create the master secret if we're
-        // creating a new session (i.e. in the full handshake).
-        //
-        svr_random = mesg.svr_random;
-
-        if (isNegotiable(mesg.cipherSuite) == false) {
-            fatalSE(Alerts.alert_illegal_parameter,
-                "Server selected improper ciphersuite " + mesg.cipherSuite);
-        }
-
-        setCipherSuite(mesg.cipherSuite);
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            handshakeHash.setFinishedAlg(cipherSuite.prfAlg.getPRFHashAlg());
-        }
-
-        if (mesg.compression_method != 0) {
-            fatalSE(Alerts.alert_illegal_parameter,
-                "compression type not supported, "
-                + mesg.compression_method);
-            // NOTREACHED
-        }
-
-        // so far so good, let's look at the session
-        if (session != null) {
-            // we tried to resume, let's see what the server decided
-            if (session.getSessionId().equals(mesg.sessionId)) {
-                // server resumed the session, let's make sure everything
-                // checks out
-
-                // Verify that the session ciphers are unchanged.
-                CipherSuite sessionSuite = session.getSuite();
-                if (cipherSuite != sessionSuite) {
-                    throw new SSLProtocolException
-                        ("Server returned wrong cipher suite for session");
-                }
-
-                // verify protocol version match
-                ProtocolVersion sessionVersion = session.getProtocolVersion();
-                if (protocolVersion != sessionVersion) {
-                    throw new SSLProtocolException
-                        ("Server resumed session with wrong protocol version");
-                }
-
-                // validate subject identity
-                if (sessionSuite.keyExchange == K_KRB5 ||
-                    sessionSuite.keyExchange == K_KRB5_EXPORT) {
-                    Principal localPrincipal = session.getLocalPrincipal();
-
-                    Subject subject = null;
-                    try {
-                        subject = AccessController.doPrivileged(
-                            new PrivilegedExceptionAction<Subject>() {
-                            public Subject run() throws Exception {
-                                return Krb5Helper.getClientSubject(getAccSE());
-                            }});
-                    } catch (PrivilegedActionException e) {
-                        subject = null;
-                        if (debug != null && Debug.isOn("session")) {
-                            System.out.println("Attempt to obtain" +
-                                        " subject failed!");
-                        }
-                    }
-
-                    if (subject != null) {
-                        // Eliminate dependency on KerberosPrincipal
-                        Set<Principal> principals =
-                            subject.getPrincipals(Principal.class);
-                        if (!principals.contains(localPrincipal)) {
-                            throw new SSLProtocolException("Server resumed" +
-                                " session with wrong subject identity");
-                        } else {
-                            if (debug != null && Debug.isOn("session"))
-                                System.out.println("Subject identity is same");
-                        }
-                    } else {
-                        if (debug != null && Debug.isOn("session"))
-                            System.out.println("Kerberos credentials are not" +
-                                " present in the current Subject; check if " +
-                                " javax.security.auth.useSubjectAsCreds" +
-                                " system property has been set to false");
-                        throw new SSLProtocolException
-                            ("Server resumed session with no subject");
-                    }
-                }
-
-                // looks fine; resume it, and update the state machine.
-                resumingSession = true;
-                state = HandshakeMessage.ht_finished - 1;
-                calculateConnectionKeys(session.getMasterSecret());
-                if (debug != null && Debug.isOn("session")) {
-                    System.out.println("%% Server resumed " + session);
-                }
-            } else {
-                // we wanted to resume, but the server refused
-                session = null;
-                if (!enableNewSession) {
-                    throw new SSLException
-                        ("New session creation is disabled");
-                }
-            }
-        }
-
-        if (resumingSession && session != null) {
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                handshakeHash.setCertificateVerifyAlg(null);
-            }
-
-            setHandshakeSessionSE(session);
-            return;
-        }
-
-        // check extensions
-        for (HelloExtension ext : mesg.extensions.list()) {
-            ExtensionType type = ext.type;
-            if ((type != ExtensionType.EXT_ELLIPTIC_CURVES)
-                    && (type != ExtensionType.EXT_EC_POINT_FORMATS)
-                    && (type != ExtensionType.EXT_SERVER_NAME)
-                    && (type != ExtensionType.EXT_RENEGOTIATION_INFO)) {
-                fatalSE(Alerts.alert_unsupported_extension,
-                    "Server sent an unsupported extension: " + type);
-            }
-        }
-
-        // Create a new session, we need to do the full handshake
-        session = new SSLSessionImpl(protocolVersion, cipherSuite,
-                            getLocalSupportedSignAlgs(),
-                            mesg.sessionId, getHostSE(), getPortSE());
-        setHandshakeSessionSE(session);
-        if (debug != null && Debug.isOn("handshake")) {
-            System.out.println("** " + cipherSuite);
-        }
-    }
-
-    /*
-     * Server's own key was either a signing-only key, or was too
-     * large for export rules ... this message holds an ephemeral
-     * RSA key to use for key exchange.
-     */
-    private void serverKeyExchange(RSA_ServerKeyExchange mesg)
-            throws IOException, GeneralSecurityException {
-        if (debug != null && Debug.isOn("handshake")) {
-            mesg.print(System.out);
-        }
-        if (!mesg.verify(serverKey, clnt_random, svr_random)) {
-            fatalSE(Alerts.alert_handshake_failure,
-                "server key exchange invalid");
-            // NOTREACHED
-        }
-        ephemeralServerKey = mesg.getPublicKey();
-    }
-
-
-    /*
-     * Diffie-Hellman key exchange.  We save the server public key and
-     * our own D-H algorithm object so we can defer key calculations
-     * until after we've sent the client key exchange message (which
-     * gives client and server some useful parallelism).
-     */
-    private void serverKeyExchange(DH_ServerKeyExchange mesg)
-            throws IOException {
-        if (debug != null && Debug.isOn("handshake")) {
-            mesg.print(System.out);
-        }
-        dh = new DHCrypt(mesg.getModulus(), mesg.getBase(),
-                                            sslContext.getSecureRandom());
-        serverDH = mesg.getServerPublicKey();
-    }
-
-    private void serverKeyExchange(ECDH_ServerKeyExchange mesg)
-            throws IOException {
-        if (debug != null && Debug.isOn("handshake")) {
-            mesg.print(System.out);
-        }
-        ECPublicKey key = mesg.getPublicKey();
-        ecdh = new ECDHCrypt(key.getParams(), sslContext.getSecureRandom());
-        ephemeralServerKey = key;
-    }
-
-    /*
-     * The server's "Hello Done" message is the client's sign that
-     * it's time to do all the hard work.
-     */
-    private void serverHelloDone(ServerHelloDone mesg) throws IOException {
-        if (debug != null && Debug.isOn("handshake")) {
-            mesg.print(System.out);
-        }
-        /*
-         * Always make sure the input has been digested before we
-         * start emitting data, to ensure the hashes are correctly
-         * computed for the Finished and CertificateVerify messages
-         * which we send (here).
-         */
-        input.digestNow();
-
-        /*
-         * FIRST ... if requested, send an appropriate Certificate chain
-         * to authenticate the client, and remember the associated private
-         * key to sign the CertificateVerify message.
-         */
-        PrivateKey signingKey = null;
-
-        if (certRequest != null) {
-            X509ExtendedKeyManager km = sslContext.getX509KeyManager();
-
-            ArrayList<String> keytypesTmp = new ArrayList<>(4);
-
-            for (int i = 0; i < certRequest.types.length; i++) {
-                String typeName;
-
-                switch (certRequest.types[i]) {
-                case CertificateRequest.cct_rsa_sign:
-                    typeName = "RSA";
-                    break;
-
-                case CertificateRequest.cct_dss_sign:
-                    typeName = "DSA";
-                    break;
-
-                case CertificateRequest.cct_ecdsa_sign:
-                    // ignore if we do not have EC crypto available
-                    typeName = JsseJce.isEcAvailable() ? "EC" : null;
-                    break;
-
-                // Fixed DH/ECDH client authentication not supported
-                case CertificateRequest.cct_rsa_fixed_dh:
-                case CertificateRequest.cct_dss_fixed_dh:
-                case CertificateRequest.cct_rsa_fixed_ecdh:
-                case CertificateRequest.cct_ecdsa_fixed_ecdh:
-                // Any other values (currently not used in TLS)
-                case CertificateRequest.cct_rsa_ephemeral_dh:
-                case CertificateRequest.cct_dss_ephemeral_dh:
-                default:
-                    typeName = null;
-                    break;
-                }
-
-                if ((typeName != null) && (!keytypesTmp.contains(typeName))) {
-                    keytypesTmp.add(typeName);
-                }
-            }
-
-            String alias = null;
-            int keytypesTmpSize = keytypesTmp.size();
-            if (keytypesTmpSize != 0) {
-                String keytypes[] =
-                        keytypesTmp.toArray(new String[keytypesTmpSize]);
-
-                if (conn != null) {
-                    alias = km.chooseClientAlias(keytypes,
-                        certRequest.getAuthorities(), conn);
-                } else {
-                    alias = km.chooseEngineClientAlias(keytypes,
-                        certRequest.getAuthorities(), engine);
-                }
-            }
-
-            CertificateMsg m1 = null;
-            if (alias != null) {
-                X509Certificate[] certs = km.getCertificateChain(alias);
-                if ((certs != null) && (certs.length != 0)) {
-                    PublicKey publicKey = certs[0].getPublicKey();
-                    // for EC, make sure we use a supported named curve
-                    if (publicKey instanceof ECPublicKey) {
-                        ECParameterSpec params =
-                            ((ECPublicKey)publicKey).getParams();
-                        int index =
-                            SupportedEllipticCurvesExtension.getCurveIndex(
-                                params);
-                        if (!SupportedEllipticCurvesExtension.isSupported(
-                                index)) {
-                            publicKey = null;
-                        }
-                    }
-                    if (publicKey != null) {
-                        m1 = new CertificateMsg(certs);
-                        signingKey = km.getPrivateKey(alias);
-                        session.setLocalPrivateKey(signingKey);
-                        session.setLocalCertificates(certs);
-                    }
-                }
-            }
-            if (m1 == null) {
-                //
-                // No appropriate cert was found ... report this to the
-                // server.  For SSLv3, send the no_certificate alert;
-                // TLS uses an empty cert chain instead.
-                //
-                if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
-                    m1 = new CertificateMsg(new X509Certificate [0]);
-                } else {
-                    warningSE(Alerts.alert_no_certificate);
-                }
-            }
-
-            //
-            // At last ... send any client certificate chain.
-            //
-            if (m1 != null) {
-                if (debug != null && Debug.isOn("handshake")) {
-                    m1.print(System.out);
-                }
-                m1.write(output);
-            }
-        }
-
-        /*
-         * SECOND ... send the client key exchange message.  The
-         * procedure used is a function of the cipher suite selected;
-         * one is always needed.
-         */
-        HandshakeMessage m2;
-
-        switch (keyExchange) {
-
-        case K_RSA:
-        case K_RSA_EXPORT:
-            if (serverKey == null) {
-                throw new SSLProtocolException
-                        ("Server did not send certificate message");
-            }
-
-            if (!(serverKey instanceof RSAPublicKey)) {
-                throw new SSLProtocolException
-                        ("Server certificate does not include an RSA key");
-            }
-
-            /*
-             * For RSA key exchange, we randomly generate a new
-             * pre-master secret and encrypt it with the server's
-             * public key.  Then we save that pre-master secret
-             * so that we can calculate the keying data later;
-             * it's a performance speedup not to do that until
-             * the client's waiting for the server response, but
-             * more of a speedup for the D-H case.
-             *
-             * If the RSA_EXPORT scheme is active, when the public
-             * key in the server certificate is less than or equal
-             * to 512 bits in length, use the cert's public key,
-             * otherwise, the ephemeral one.
-             */
-            PublicKey key;
-            if (keyExchange == K_RSA) {
-                key = serverKey;
-            } else {    // K_RSA_EXPORT
-                if (JsseJce.getRSAKeyLength(serverKey) <= 512) {
-                    // extraneous ephemeralServerKey check done
-                    // above in processMessage()
-                    key = serverKey;
-                } else {
-                    if (ephemeralServerKey == null) {
-                        throw new SSLProtocolException("Server did not send" +
-                            " a RSA_EXPORT Server Key Exchange message");
-                    }
-                    key = ephemeralServerKey;
-                }
-            }
-
-            m2 = new RSAClientKeyExchange(protocolVersion, maxProtocolVersion,
-                                sslContext.getSecureRandom(), key);
-            break;
-        case K_DH_RSA:
-        case K_DH_DSS:
-            /*
-             * For DH Key exchange, we only need to make sure the server
-             * knows our public key, so we calculate the same pre-master
-             * secret.
-             *
-             * For certs that had DH keys in them, we send an empty
-             * handshake message (no key) ... we flag this case by
-             * passing a null "dhPublic" value.
-             *
-             * Otherwise we send ephemeral DH keys, unsigned.
-             */
-            // if (useDH_RSA || useDH_DSS)
-            m2 = new DHClientKeyExchange();
-            break;
-        case K_DHE_RSA:
-        case K_DHE_DSS:
-        case K_DH_ANON:
-            if (dh == null) {
-                throw new SSLProtocolException
-                    ("Server did not send a DH Server Key Exchange message");
-            }
-            m2 = new DHClientKeyExchange(dh.getPublicKey());
-            break;
-        case K_ECDHE_RSA:
-        case K_ECDHE_ECDSA:
-        case K_ECDH_ANON:
-            if (ecdh == null) {
-                throw new SSLProtocolException
-                    ("Server did not send a ECDH Server Key Exchange message");
-            }
-            m2 = new ECDHClientKeyExchange(ecdh.getPublicKey());
-            break;
-        case K_ECDH_RSA:
-        case K_ECDH_ECDSA:
-            if (serverKey == null) {
-                throw new SSLProtocolException
-                        ("Server did not send certificate message");
-            }
-            if (serverKey instanceof ECPublicKey == false) {
-                throw new SSLProtocolException
-                        ("Server certificate does not include an EC key");
-            }
-            ECParameterSpec params = ((ECPublicKey)serverKey).getParams();
-            ecdh = new ECDHCrypt(params, sslContext.getSecureRandom());
-            m2 = new ECDHClientKeyExchange(ecdh.getPublicKey());
-            break;
-        case K_KRB5:
-        case K_KRB5_EXPORT:
-            String hostname = getHostSE();
-            if (hostname == null) {
-                throw new IOException("Hostname is required" +
-                                " to use Kerberos cipher suites");
-            }
-            KerberosClientKeyExchange kerberosMsg =
-                new KerberosClientKeyExchange(
-                    hostname, isLoopbackSE(), getAccSE(), protocolVersion,
-                sslContext.getSecureRandom());
-            // Record the principals involved in exchange
-            session.setPeerPrincipal(kerberosMsg.getPeerPrincipal());
-            session.setLocalPrincipal(kerberosMsg.getLocalPrincipal());
-            m2 = kerberosMsg;
-            break;
-        default:
-            // somethings very wrong
-            throw new RuntimeException
-                                ("Unsupported key exchange: " + keyExchange);
-        }
-        if (debug != null && Debug.isOn("handshake")) {
-            m2.print(System.out);
-        }
-        m2.write(output);
-
-
-        /*
-         * THIRD, send a "change_cipher_spec" record followed by the
-         * "Finished" message.  We flush the messages we've queued up, to
-         * get concurrency between client and server.  The concurrency is
-         * useful as we calculate the master secret, which is needed both
-         * to compute the "Finished" message, and to compute the keys used
-         * to protect all records following the change_cipher_spec.
-         */
-
-        output.doHashes();
-        output.flush();
-
-        /*
-         * We deferred calculating the master secret and this connection's
-         * keying data; we do it now.  Deferring this calculation is good
-         * from a performance point of view, since it lets us do it during
-         * some time that network delays and the server's own calculations
-         * would otherwise cause to be "dead" in the critical path.
-         */
-        SecretKey preMasterSecret;
-        switch (keyExchange) {
-        case K_RSA:
-        case K_RSA_EXPORT:
-            preMasterSecret = ((RSAClientKeyExchange)m2).preMaster;
-            break;
-        case K_KRB5:
-        case K_KRB5_EXPORT:
-            byte[] secretBytes =
-                ((KerberosClientKeyExchange)m2).getUnencryptedPreMasterSecret();
-            preMasterSecret = new SecretKeySpec(secretBytes,
-                "TlsPremasterSecret");
-            break;
-        case K_DHE_RSA:
-        case K_DHE_DSS:
-        case K_DH_ANON:
-            preMasterSecret = dh.getAgreedSecret(serverDH, true);
-            break;
-        case K_ECDHE_RSA:
-        case K_ECDHE_ECDSA:
-        case K_ECDH_ANON:
-            preMasterSecret = ecdh.getAgreedSecret(ephemeralServerKey);
-            break;
-        case K_ECDH_RSA:
-        case K_ECDH_ECDSA:
-            preMasterSecret = ecdh.getAgreedSecret(serverKey);
-            break;
-        default:
-            throw new IOException("Internal error: unknown key exchange "
-                + keyExchange);
-        }
-
-        calculateKeys(preMasterSecret, null);
-
-        /*
-         * FOURTH, if we sent a Certificate, we need to send a signed
-         * CertificateVerify (unless the key in the client's certificate
-         * was a Diffie-Hellman key).).
-         *
-         * This uses a hash of the previous handshake messages ... either
-         * a nonfinal one (if the particular implementation supports it)
-         * or else using the third element in the arrays of hashes being
-         * computed.
-         */
-        if (signingKey != null) {
-            CertificateVerify m3;
-            try {
-                SignatureAndHashAlgorithm preferableSignatureAlgorithm = null;
-                if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                    preferableSignatureAlgorithm =
-                        SignatureAndHashAlgorithm.getPreferableAlgorithm(
-                            peerSupportedSignAlgs, signingKey.getAlgorithm(),
-                            signingKey);
-
-                    if (preferableSignatureAlgorithm == null) {
-                        throw new SSLHandshakeException(
-                            "No supported signature algorithm");
-                    }
-
-                    String hashAlg =
-                        SignatureAndHashAlgorithm.getHashAlgorithmName(
-                                preferableSignatureAlgorithm);
-                    if (hashAlg == null || hashAlg.length() == 0) {
-                        throw new SSLHandshakeException(
-                                "No supported hash algorithm");
-                    }
-
-                    handshakeHash.setCertificateVerifyAlg(hashAlg);
-                }
-
-                m3 = new CertificateVerify(protocolVersion, handshakeHash,
-                    signingKey, session.getMasterSecret(),
-                    sslContext.getSecureRandom(),
-                    preferableSignatureAlgorithm);
-            } catch (GeneralSecurityException e) {
-                fatalSE(Alerts.alert_handshake_failure,
-                    "Error signing certificate verify", e);
-                // NOTREACHED, make compiler happy
-                m3 = null;
-            }
-            if (debug != null && Debug.isOn("handshake")) {
-                m3.print(System.out);
-            }
-            m3.write(output);
-            output.doHashes();
-        } else {
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                handshakeHash.setCertificateVerifyAlg(null);
-            }
-        }
-
-        /*
-         * OK, that's that!
-         */
-        sendChangeCipherAndFinish(false);
-    }
-
-
-    /*
-     * "Finished" is the last handshake message sent.  If we got this
-     * far, the MAC has been validated post-decryption.  We validate
-     * the two hashes here as an additional sanity check, protecting
-     * the handshake against various active attacks.
-     */
-    private void serverFinished(Finished mesg) throws IOException {
-        if (debug != null && Debug.isOn("handshake")) {
-            mesg.print(System.out);
-        }
-
-        boolean verified = mesg.verify(handshakeHash, Finished.SERVER,
-            session.getMasterSecret());
-
-        if (!verified) {
-            fatalSE(Alerts.alert_illegal_parameter,
-                       "server 'finished' message doesn't verify");
-            // NOTREACHED
-        }
-
-        /*
-         * save server verify data for secure renegotiation
-         */
-        if (secureRenegotiation) {
-            serverVerifyData = mesg.getVerifyData();
-        }
-
-        /*
-         * OK, it verified.  If we're doing the fast handshake, add that
-         * "Finished" message to the hash of handshake messages, then send
-         * our own change_cipher_spec and Finished message for the server
-         * to verify in turn.  These are the last handshake messages.
-         *
-         * In any case, update the session cache.  We're done handshaking,
-         * so there are no threats any more associated with partially
-         * completed handshakes.
-         */
-        if (resumingSession) {
-            input.digestNow();
-            sendChangeCipherAndFinish(true);
-        }
-        session.setLastAccessedTime(System.currentTimeMillis());
-
-        if (!resumingSession) {
-            if (session.isRejoinable()) {
-                ((SSLSessionContextImpl) sslContext
-                        .engineGetClientSessionContext())
-                        .put(session);
-                if (debug != null && Debug.isOn("session")) {
-                    System.out.println("%% Cached client session: " + session);
-                }
-            } else if (debug != null && Debug.isOn("session")) {
-                System.out.println(
-                    "%% Didn't cache non-resumable client session: "
-                    + session);
-            }
-        }
-    }
-
-
-    /*
-     * Send my change-cipher-spec and Finished message ... done as the
-     * last handshake act in either the short or long sequences.  In
-     * the short one, we've already seen the server's Finished; in the
-     * long one, we wait for it now.
-     */
-    private void sendChangeCipherAndFinish(boolean finishedTag)
-            throws IOException {
-        Finished mesg = new Finished(protocolVersion, handshakeHash,
-            Finished.CLIENT, session.getMasterSecret(), cipherSuite);
-
-        /*
-         * Send the change_cipher_spec message, then the Finished message
-         * which we just calculated (and protected using the keys we just
-         * calculated).  Server responds with its Finished message, except
-         * in the "fast handshake" (resume session) case.
-         */
-        sendChangeCipherSpec(mesg, finishedTag);
-
-        /*
-         * save client verify data for secure renegotiation
-         */
-        if (secureRenegotiation) {
-            clientVerifyData = mesg.getVerifyData();
-        }
-
-        /*
-         * Update state machine so server MUST send 'finished' next.
-         * (In "long" handshake case; in short case, we're responding
-         * to its message.)
-         */
-        state = HandshakeMessage.ht_finished - 1;
-    }
-
-
-    /*
-     * Returns a ClientHello message to kickstart renegotiations
-     */
-    HandshakeMessage getKickstartMessage() throws SSLException {
-        // session ID of the ClientHello message
-        SessionId sessionId = SSLSessionImpl.nullSession.getSessionId();
-
-        // a list of cipher suites sent by the client
-        CipherSuiteList cipherSuites = getActiveCipherSuites();
-
-        // set the max protocol version this client is supporting.
-        maxProtocolVersion = protocolVersion;
-
-        //
-        // Try to resume an existing session.  This might be mandatory,
-        // given certain API options.
-        //
-        session = ((SSLSessionContextImpl)sslContext
-                        .engineGetClientSessionContext())
-                        .get(getHostSE(), getPortSE());
-        if (debug != null && Debug.isOn("session")) {
-            if (session != null) {
-                System.out.println("%% Client cached "
-                    + session
-                    + (session.isRejoinable() ? "" : " (not rejoinable)"));
-            } else {
-                System.out.println("%% No cached client session");
-            }
-        }
-        if ((session != null) && (session.isRejoinable() == false)) {
-            session = null;
-        }
-
-        if (session != null) {
-            CipherSuite sessionSuite = session.getSuite();
-            ProtocolVersion sessionVersion = session.getProtocolVersion();
-            if (isNegotiable(sessionSuite) == false) {
-                if (debug != null && Debug.isOn("session")) {
-                    System.out.println("%% can't resume, unavailable cipher");
-                }
-                session = null;
-            }
-
-            if ((session != null) && !isNegotiable(sessionVersion)) {
-                if (debug != null && Debug.isOn("session")) {
-                    System.out.println("%% can't resume, protocol disabled");
-                }
-                session = null;
-            }
-
-            if (session != null) {
-                if (debug != null) {
-                    if (Debug.isOn("handshake") || Debug.isOn("session")) {
-                        System.out.println("%% Try resuming " + session
-                            + " from port " + getLocalPortSE());
-                    }
-                }
-
-                sessionId = session.getSessionId();
-                maxProtocolVersion = sessionVersion;
-
-                // Update SSL version number in underlying SSL socket and
-                // handshake output stream, so that the output records (at the
-                // record layer) have the correct version
-                setVersion(sessionVersion);
-            }
-
-            /*
-             * Force use of the previous session ciphersuite, and
-             * add the SCSV if enabled.
-             */
-            if (!enableNewSession) {
-                if (session == null) {
-                    throw new SSLHandshakeException(
-                        "Can't reuse existing SSL client session");
-                }
-
-                Collection<CipherSuite> cipherList = new ArrayList<>(2);
-                cipherList.add(sessionSuite);
-                if (!secureRenegotiation &&
-                        cipherSuites.contains(CipherSuite.C_SCSV)) {
-                    cipherList.add(CipherSuite.C_SCSV);
-                }   // otherwise, renegotiation_info extension will be used
-
-                cipherSuites = new CipherSuiteList(cipherList);
-            }
-        }
-
-        if (session == null && !enableNewSession) {
-            throw new SSLHandshakeException("No existing session to resume");
-        }
-
-        // exclude SCSV for secure renegotiation
-        if (secureRenegotiation && cipherSuites.contains(CipherSuite.C_SCSV)) {
-            Collection<CipherSuite> cipherList =
-                        new ArrayList<>(cipherSuites.size() - 1);
-            for (CipherSuite suite : cipherSuites.collection()) {
-                if (suite != CipherSuite.C_SCSV) {
-                    cipherList.add(suite);
-                }
-            }
-
-            cipherSuites = new CipherSuiteList(cipherList);
-        }
-
-        // make sure there is a negotiable cipher suite.
-        boolean negotiable = false;
-        for (CipherSuite suite : cipherSuites.collection()) {
-            if (isNegotiable(suite)) {
-                negotiable = true;
-                break;
-            }
-        }
-
-        if (!negotiable) {
-            throw new SSLHandshakeException("No negotiable cipher suite");
-        }
-
-        // Not a TLS1.2+ handshake
-        // For SSLv2Hello, HandshakeHash.reset() will be called, so we
-        // cannot call HandshakeHash.protocolDetermined() here. As it does
-        // not follow the spec that HandshakeHash.reset() can be only be
-        // called before protocolDetermined.
-        // if (maxProtocolVersion.v < ProtocolVersion.TLS12.v) {
-        //     handshakeHash.protocolDetermined(maxProtocolVersion);
-        // }
-
-        // create the ClientHello message
-        ClientHello clientHelloMessage = new ClientHello(
-                sslContext.getSecureRandom(), maxProtocolVersion,
-                sessionId, cipherSuites);
-
-        // add signature_algorithm extension
-        if (maxProtocolVersion.v >= ProtocolVersion.TLS12.v) {
-            // we will always send the signature_algorithm extension
-            Collection<SignatureAndHashAlgorithm> localSignAlgs =
-                                                getLocalSupportedSignAlgs();
-            if (localSignAlgs.isEmpty()) {
-                throw new SSLHandshakeException(
-                            "No supported signature algorithm");
-            }
-
-            clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs);
-        }
-
-        // add server_name extension
-        if (enableSNIExtension) {
-            // We cannot use the hostname resolved from name services.  For
-            // virtual hosting, multiple hostnames may be bound to the same IP
-            // address, so the hostname resolved from name services is not
-            // reliable.
-            String hostname = getRawHostnameSE();
-
-            // we only allow FQDN
-            if (hostname != null && hostname.indexOf('.') > 0 &&
-                    !IPAddressUtil.isIPv4LiteralAddress(hostname) &&
-                    !IPAddressUtil.isIPv6LiteralAddress(hostname)) {
-                clientHelloMessage.addServerNameIndicationExtension(hostname);
-            }
-        }
-
-        // reset the client random cookie
-        clnt_random = clientHelloMessage.clnt_random;
-
-        /*
-         * need to set the renegotiation_info extension for:
-         * 1: secure renegotiation
-         * 2: initial handshake and no SCSV in the ClientHello
-         * 3: insecure renegotiation and no SCSV in the ClientHello
-         */
-        if (secureRenegotiation ||
-                !cipherSuites.contains(CipherSuite.C_SCSV)) {
-            clientHelloMessage.addRenegotiationInfoExtension(clientVerifyData);
-        }
-
-        return clientHelloMessage;
-    }
-
-    /*
-     * Fault detected during handshake.
-     */
-    void handshakeAlert(byte description) throws SSLProtocolException {
-        String message = Alerts.alertDescription(description);
-
-        if (debug != null && Debug.isOn("handshake")) {
-            System.out.println("SSL - handshake alert: " + message);
-        }
-        throw new SSLProtocolException("handshake alert:  " + message);
-    }
-
-    /*
-     * Unless we are using an anonymous ciphersuite, the server always
-     * sends a certificate message (for the CipherSuites we currently
-     * support). The trust manager verifies the chain for us.
-     */
-    private void serverCertificate(CertificateMsg mesg) throws IOException {
-        if (debug != null && Debug.isOn("handshake")) {
-            mesg.print(System.out);
-        }
-        X509Certificate[] peerCerts = mesg.getCertificateChain();
-        if (peerCerts.length == 0) {
-            fatalSE(Alerts.alert_bad_certificate,
-                "empty certificate chain");
-        }
-        // ask the trust manager to verify the chain
-        X509TrustManager tm = sslContext.getX509TrustManager();
-        try {
-            // find out the key exchange algorithm used
-            // use "RSA" for non-ephemeral "RSA_EXPORT"
-            String keyExchangeString;
-            if (keyExchange == K_RSA_EXPORT && !serverKeyExchangeReceived) {
-                keyExchangeString = K_RSA.name;
-            } else {
-                keyExchangeString = keyExchange.name;
-            }
-
-            if (tm instanceof X509ExtendedTrustManager) {
-                if (conn != null) {
-                    ((X509ExtendedTrustManager)tm).checkServerTrusted(
-                        peerCerts.clone(),
-                        keyExchangeString,
-                        conn);
-                } else {
-                    ((X509ExtendedTrustManager)tm).checkServerTrusted(
-                        peerCerts.clone(),
-                        keyExchangeString,
-                        engine);
-                }
-            } else {
-                // Unlikely to happen, because we have wrapped the old
-                // X509TrustManager with the new X509ExtendedTrustManager.
-                throw new CertificateException(
-                    "Improper X509TrustManager implementation");
-            }
-        } catch (CertificateException e) {
-            // This will throw an exception, so include the original error.
-            fatalSE(Alerts.alert_certificate_unknown, e);
-        }
-        session.setPeerCertificates(peerCerts);
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/DHClientKeyExchange.java b/ojluni/src/main/java/sun/security/ssl/DHClientKeyExchange.java
deleted file mode 100755
index b450098..0000000
--- a/ojluni/src/main/java/sun/security/ssl/DHClientKeyExchange.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.math.BigInteger;
-import javax.net.ssl.SSLHandshakeException;
-
-/*
- * Message used by clients to send their Diffie-Hellman public
- * keys to servers.
- *
- * @author David Brownell
- */
-final class DHClientKeyExchange extends HandshakeMessage {
-
-    int messageType() {
-        return ht_client_key_exchange;
-    }
-
-    /*
-     * This value may be empty if it was included in the
-     * client's certificate ...
-     */
-    private byte dh_Yc[];               // 1 to 2^16 -1 bytes
-
-    BigInteger getClientPublicKey() {
-        return dh_Yc == null ? null : new BigInteger(1, dh_Yc);
-    }
-
-    /*
-     * Either pass the client's public key explicitly (because it's
-     * using DHE or DH_anon), or implicitly (the public key was in the
-     * certificate).
-     */
-    DHClientKeyExchange(BigInteger publicKey) {
-        dh_Yc = toByteArray(publicKey);
-    }
-
-    DHClientKeyExchange() {
-        dh_Yc = null;
-    }
-
-    /*
-     * Get the client's public key either explicitly or implicitly.
-     * (It's ugly to have an empty record be sent in the latter case,
-     * but that's what the protocol spec requires.)
-     */
-    DHClientKeyExchange(HandshakeInStream input) throws IOException {
-        if (input.available() >= 2) {
-            dh_Yc = input.getBytes16();
-        } else {
-            // currently, we don't support cipher suites that requires
-            // implicit public key of client.
-            throw new SSLHandshakeException(
-                    "Unsupported implicit client DiffieHellman public key");
-        }
-    }
-
-    int messageLength() {
-        if (dh_Yc == null) {
-            return 0;
-        } else {
-            return dh_Yc.length + 2;
-        }
-    }
-
-    void send(HandshakeOutStream s) throws IOException {
-        if (dh_Yc != null && dh_Yc.length != 0) {
-            s.putBytes16(dh_Yc);
-        }
-    }
-
-    void print(PrintStream s) throws IOException {
-        s.println("*** ClientKeyExchange, DH");
-
-        if (debug != null && Debug.isOn("verbose")) {
-            Debug.println(s, "DH Public key", dh_Yc);
-        }
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/DHCrypt.java b/ojluni/src/main/java/sun/security/ssl/DHCrypt.java
deleted file mode 100755
index ae9118f..0000000
--- a/ojluni/src/main/java/sun/security/ssl/DHCrypt.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.math.BigInteger;
-import java.security.*;
-import java.io.IOException;
-import javax.net.ssl.SSLHandshakeException;
-import javax.crypto.SecretKey;
-import javax.crypto.KeyAgreement;
-import javax.crypto.interfaces.DHPublicKey;
-import javax.crypto.spec.*;
-
-import sun.security.util.KeyUtil;
-
-/**
- * This class implements the Diffie-Hellman key exchange algorithm.
- * D-H means combining your private key with your partners public key to
- * generate a number. The peer does the same with its private key and our
- * public key. Through the magic of Diffie-Hellman we both come up with the
- * same number. This number is secret (discounting MITM attacks) and hence
- * called the shared secret. It has the same length as the modulus, e.g. 512
- * or 1024 bit. Man-in-the-middle attacks are typically countered by an
- * independent authentication step using certificates (RSA, DSA, etc.).
- *
- * The thing to note is that the shared secret is constant for two partners
- * with constant private keys. This is often not what we want, which is why
- * it is generally a good idea to create a new private key for each session.
- * Generating a private key involves one modular exponentiation assuming
- * suitable D-H parameters are available.
- *
- * General usage of this class (TLS DHE case):
- *  . if we are server, call DHCrypt(keyLength,random). This generates
- *    an ephemeral keypair of the request length.
- *  . if we are client, call DHCrypt(modulus, base, random). This
- *    generates an ephemeral keypair using the parameters specified by
- *    the server.
- *  . send parameters and public value to remote peer
- *  . receive peers ephemeral public key
- *  . call getAgreedSecret() to calculate the shared secret
- *
- * In TLS the server chooses the parameter values itself, the client must use
- * those sent to it by the server.
- *
- * The use of ephemeral keys as described above also achieves what is called
- * "forward secrecy". This means that even if the authentication keys are
- * broken at a later date, the shared secret remains secure. The session is
- * compromised only if the authentication keys are already broken at the
- * time the key exchange takes place and an active MITM attack is used.
- * This is in contrast to straightforward encrypting RSA key exchanges.
- *
- * @author David Brownell
- */
-final class DHCrypt {
-
-    // group parameters (prime modulus and generator)
-    private BigInteger modulus;                 // P (aka N)
-    private BigInteger base;                    // G (aka alpha)
-
-    // our private key (including private component x)
-    private PrivateKey privateKey;
-
-    // public component of our key, X = (g ^ x) mod p
-    private BigInteger publicValue;             // X (aka y)
-
-    // the times to recove from failure if public key validation
-    private static int MAX_FAILOVER_TIMES = 2;
-
-    /**
-     * Generate a Diffie-Hellman keypair of the specified size.
-     */
-    DHCrypt(int keyLength, SecureRandom random) {
-        try {
-            KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman");
-            kpg.initialize(keyLength, random);
-
-            DHPublicKeySpec spec = generateDHPublicKeySpec(kpg);
-            if (spec == null) {
-                throw new RuntimeException("Could not generate DH keypair");
-            }
-
-            publicValue = spec.getY();
-            modulus = spec.getP();
-            base = spec.getG();
-        } catch (GeneralSecurityException e) {
-            throw new RuntimeException("Could not generate DH keypair", e);
-        }
-    }
-
-
-    /**
-     * Generate a Diffie-Hellman keypair using the specified parameters.
-     *
-     * @param modulus the Diffie-Hellman modulus P
-     * @param base the Diffie-Hellman base G
-     */
-    DHCrypt(BigInteger modulus, BigInteger base, SecureRandom random) {
-        this.modulus = modulus;
-        this.base = base;
-        try {
-            KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman");
-            DHParameterSpec params = new DHParameterSpec(modulus, base);
-            kpg.initialize(params, random);
-
-            DHPublicKeySpec spec = generateDHPublicKeySpec(kpg);
-            if (spec == null) {
-                throw new RuntimeException("Could not generate DH keypair");
-            }
-
-            publicValue = spec.getY();
-        } catch (GeneralSecurityException e) {
-            throw new RuntimeException("Could not generate DH keypair", e);
-        }
-    }
-
-
-    static DHPublicKeySpec getDHPublicKeySpec(PublicKey key) {
-        if (key instanceof DHPublicKey) {
-            DHPublicKey dhKey = (DHPublicKey)key;
-            DHParameterSpec params = dhKey.getParams();
-            return new DHPublicKeySpec(dhKey.getY(),
-                                    params.getP(), params.getG());
-        }
-        try {
-            KeyFactory factory = JsseJce.getKeyFactory("DH");
-            return factory.getKeySpec(key, DHPublicKeySpec.class);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-
-    /** Returns the Diffie-Hellman modulus. */
-    BigInteger getModulus() {
-        return modulus;
-    }
-
-    /** Returns the Diffie-Hellman base (generator).  */
-    BigInteger getBase() {
-        return base;
-    }
-
-    /**
-     * Gets the public key of this end of the key exchange.
-     */
-    BigInteger getPublicKey() {
-        return publicValue;
-    }
-
-    /**
-     * Get the secret data that has been agreed on through Diffie-Hellman
-     * key agreement protocol.  Note that in the two party protocol, if
-     * the peer keys are already known, no other data needs to be sent in
-     * order to agree on a secret.  That is, a secured message may be
-     * sent without any mandatory round-trip overheads.
-     *
-     * <P>It is illegal to call this member function if the private key
-     * has not been set (or generated).
-     *
-     * @param  peerPublicKey the peer's public key.
-     * @param  keyIsValidated whether the {@code peerPublicKey} has beed
-     *         validated
-     * @return the secret, which is an unsigned big-endian integer
-     *         the same size as the Diffie-Hellman modulus.
-     */
-    SecretKey getAgreedSecret(BigInteger peerPublicValue,
-            boolean keyIsValidated) throws IOException {
-        try {
-            KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman");
-            DHPublicKeySpec spec =
-                        new DHPublicKeySpec(peerPublicValue, modulus, base);
-            PublicKey publicKey = kf.generatePublic(spec);
-            KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman");
-
-            // validate the Diffie-Hellman public key
-            if (!keyIsValidated &&
-                    !KeyUtil.isOracleJCEProvider(ka.getProvider().getName())) {
-                try {
-                    KeyUtil.validate(spec);
-                } catch (InvalidKeyException ike) {
-                    // prefer handshake_failure alert to internal_error alert
-                    throw new SSLHandshakeException(ike.getMessage());
-                }
-            }
-
-            ka.init(privateKey);
-            ka.doPhase(publicKey, true);
-            return ka.generateSecret("TlsPremasterSecret");
-        } catch (GeneralSecurityException e) {
-            throw new RuntimeException("Could not generate secret", e);
-        }
-    }
-
-    // Generate and validate DHPublicKeySpec
-    private DHPublicKeySpec generateDHPublicKeySpec(KeyPairGenerator kpg)
-            throws GeneralSecurityException {
-
-        boolean doExtraValiadtion =
-                    (!KeyUtil.isOracleJCEProvider(kpg.getProvider().getName()));
-        for (int i = 0; i <= MAX_FAILOVER_TIMES; i++) {
-            KeyPair kp = kpg.generateKeyPair();
-            privateKey = kp.getPrivate();
-            DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic());
-
-            // validate the Diffie-Hellman public key
-            if (doExtraValiadtion) {
-                try {
-                    KeyUtil.validate(spec);
-                } catch (InvalidKeyException ivke) {
-                    if (i == MAX_FAILOVER_TIMES) {
-                        throw ivke;
-                    }
-                    // otherwise, ignore the exception and try the next one
-                    continue;
-                }
-            }
-
-            return spec;
-        }
-
-        return null;
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/Debug.java b/ojluni/src/main/java/sun/security/ssl/Debug.java
deleted file mode 100755
index a270816..0000000
--- a/ojluni/src/main/java/sun/security/ssl/Debug.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.io.PrintStream;
-import java.security.AccessController;
-import java.util.Locale;
-
-import sun.security.action.GetPropertyAction;
-
-/**
- * This class has be shamefully lifted from sun.security.util.Debug
- *
- * @author Gary Ellison
- */
-public class Debug {
-
-    private String prefix;
-
-    private static String args;
-
-    static {
-        args = java.security.AccessController.doPrivileged(
-            new GetPropertyAction("javax.net.debug", ""));
-        args = args.toLowerCase(Locale.ENGLISH);
-        if (args.equals("help")) {
-            Help();
-        }
-    }
-
-    public static void Help()
-    {
-        System.err.println();
-        System.err.println("all            turn on all debugging");
-        System.err.println("ssl            turn on ssl debugging");
-        System.err.println();
-        System.err.println("The following can be used with ssl:");
-        System.err.println("\trecord       enable per-record tracing");
-        System.err.println("\thandshake    print each handshake message");
-        System.err.println("\tkeygen       print key generation data");
-        System.err.println("\tsession      print session activity");
-        System.err.println("\tdefaultctx   print default SSL initialization");
-        System.err.println("\tsslctx       print SSLContext tracing");
-        System.err.println("\tsessioncache print session cache tracing");
-        System.err.println("\tkeymanager   print key manager tracing");
-        System.err.println("\ttrustmanager print trust manager tracing");
-        System.err.println("\tpluggability print pluggability tracing");
-        System.err.println();
-        System.err.println("\thandshake debugging can be widened with:");
-        System.err.println("\tdata         hex dump of each handshake message");
-        System.err.println("\tverbose      verbose handshake message printing");
-        System.err.println();
-        System.err.println("\trecord debugging can be widened with:");
-        System.err.println("\tplaintext    hex dump of record plaintext");
-        System.err.println("\tpacket       print raw SSL/TLS packets");
-        System.err.println();
-        System.exit(0);
-    }
-
-    /**
-     * Get a Debug object corresponding to whether or not the given
-     * option is set. Set the prefix to be the same as option.
-     */
-
-    public static Debug getInstance(String option)
-    {
-        return getInstance(option, option);
-    }
-
-    /**
-     * Get a Debug object corresponding to whether or not the given
-     * option is set. Set the prefix to be prefix.
-     */
-    public static Debug getInstance(String option, String prefix)
-    {
-        if (isOn(option)) {
-            Debug d = new Debug();
-            d.prefix = prefix;
-            return d;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * True if the property "javax.net.debug" contains the
-     * string "option".
-     */
-    public static boolean isOn(String option)
-    {
-        if (args == null) {
-            return false;
-        } else {
-            int n = 0;
-            option = option.toLowerCase(Locale.ENGLISH);
-
-            if (args.indexOf("all") != -1) {
-                return true;
-            } else if ((n = args.indexOf("ssl")) != -1) {
-                if (args.indexOf("sslctx", n) == -1) {
-                    // don't enable data and plaintext options by default
-                    if (!(option.equals("data")
-                        || option.equals("packet")
-                        || option.equals("plaintext"))) {
-                        return true;
-                    }
-                }
-            }
-            return (args.indexOf(option) != -1);
-        }
-    }
-
-    /**
-     * print a message to stderr that is prefixed with the prefix
-     * created from the call to getInstance.
-     */
-
-    public void println(String message)
-    {
-        System.err.println(prefix + ": "+message);
-    }
-
-    /**
-     * print a blank line to stderr that is prefixed with the prefix.
-     */
-
-    public void println()
-    {
-        System.err.println(prefix + ":");
-    }
-
-    /**
-     * print a message to stderr that is prefixed with the prefix.
-     */
-
-    public static void println(String prefix, String message)
-    {
-        System.err.println(prefix + ": "+message);
-    }
-
-    public static void println(PrintStream s, String name, byte[] data) {
-        s.print(name + ":  { ");
-        if (data == null) {
-            s.print("null");
-        } else {
-            for (int i = 0; i < data.length; i++) {
-                if (i != 0) s.print(", ");
-                s.print(data[i] & 0x0ff);
-            }
-        }
-        s.println(" }");
-    }
-
-    /**
-     * Return the value of the boolean System property propName.
-     *
-     * Note use of doPrivileged(). Do make accessible to applications.
-     */
-    static boolean getBooleanProperty(String propName, boolean defaultValue) {
-        // if set, require value of either true or false
-        String b = AccessController.doPrivileged(
-                new GetPropertyAction(propName));
-        if (b == null) {
-            return defaultValue;
-        } else if (b.equalsIgnoreCase("false")) {
-            return false;
-        } else if (b.equalsIgnoreCase("true")) {
-            return true;
-        } else {
-            throw new RuntimeException("Value of " + propName
-                + " must either be 'true' or 'false'");
-        }
-    }
-
-    static String toString(byte[] b) {
-        return sun.security.util.Debug.toString(b);
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/ECDHClientKeyExchange.java b/ojluni/src/main/java/sun/security/ssl/ECDHClientKeyExchange.java
deleted file mode 100755
index d89945c..0000000
--- a/ojluni/src/main/java/sun/security/ssl/ECDHClientKeyExchange.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2006, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.io.IOException;
-import java.io.PrintStream;
-
-import java.security.PublicKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.*;
-
-/**
- * ClientKeyExchange message for all ECDH based key exchange methods. It
- * contains the client's ephemeral public value.
- *
- * @since   1.6
- * @author  Andreas Sterbenz
- */
-final class ECDHClientKeyExchange extends HandshakeMessage {
-
-    int messageType() {
-        return ht_client_key_exchange;
-    }
-
-    private byte[] encodedPoint;
-
-    byte[] getEncodedPoint() {
-        return encodedPoint;
-    }
-
-    // Called by the client with its ephemeral public key.
-    ECDHClientKeyExchange(PublicKey publicKey) {
-        ECPublicKey ecKey = (ECPublicKey)publicKey;
-        ECPoint point = ecKey.getW();
-        ECParameterSpec params = ecKey.getParams();
-        encodedPoint = JsseJce.encodePoint(point, params.getCurve());
-    }
-
-    ECDHClientKeyExchange(HandshakeInStream input) throws IOException {
-        encodedPoint = input.getBytes8();
-    }
-
-    int messageLength() {
-        return encodedPoint.length + 1;
-    }
-
-    void send(HandshakeOutStream s) throws IOException {
-        s.putBytes8(encodedPoint);
-    }
-
-    void print(PrintStream s) throws IOException {
-        s.println("*** ECDHClientKeyExchange");
-
-        if (debug != null && Debug.isOn("verbose")) {
-            Debug.println(s, "ECDH Public value", encodedPoint);
-        }
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/ECDHCrypt.java b/ojluni/src/main/java/sun/security/ssl/ECDHCrypt.java
deleted file mode 100755
index 84dc467..0000000
--- a/ojluni/src/main/java/sun/security/ssl/ECDHCrypt.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2006, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.security.*;
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.*;
-
-import javax.crypto.SecretKey;
-import javax.crypto.KeyAgreement;
-import javax.crypto.spec.*;
-
-/**
- * Helper class for the ECDH key exchange. It generates the appropriate
- * ephemeral keys as necessary and performs the actual shared secret derivation.
- *
- * @since   1.6
- * @author  Andreas Sterbenz
- */
-final class ECDHCrypt {
-
-    // our private key
-    private PrivateKey privateKey;
-
-    // our public key
-    private ECPublicKey publicKey;
-
-    // Called by ServerHandshaker for static ECDH
-    ECDHCrypt(PrivateKey privateKey, PublicKey publicKey) {
-        this.privateKey = privateKey;
-        this.publicKey = (ECPublicKey)publicKey;
-    }
-
-    // Called by ServerHandshaker for ephemeral ECDH
-    ECDHCrypt(String curveName, SecureRandom random) {
-        try {
-            KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("EC");
-            ECGenParameterSpec params = new ECGenParameterSpec(curveName);
-            kpg.initialize(params, random);
-            KeyPair kp = kpg.generateKeyPair();
-            privateKey = kp.getPrivate();
-            publicKey = (ECPublicKey)kp.getPublic();
-        } catch (GeneralSecurityException e) {
-            throw new RuntimeException("Could not generate DH keypair", e);
-        }
-    }
-
-    // Called by ClientHandshaker with params it received from the server
-    ECDHCrypt(ECParameterSpec params, SecureRandom random) {
-        try {
-            KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("EC");
-            kpg.initialize(params, random);
-            KeyPair kp = kpg.generateKeyPair();
-            privateKey = kp.getPrivate();
-            publicKey = (ECPublicKey)kp.getPublic();
-        } catch (GeneralSecurityException e) {
-            throw new RuntimeException("Could not generate DH keypair", e);
-        }
-    }
-
-    /**
-     * Gets the public key of this end of the key exchange.
-     */
-    PublicKey getPublicKey() {
-        return publicKey;
-    }
-
-    // called by ClientHandshaker with either the server's static or ephemeral public key
-    SecretKey getAgreedSecret(PublicKey peerPublicKey) {
-        try {
-            KeyAgreement ka = JsseJce.getKeyAgreement("ECDH");
-            ka.init(privateKey);
-            ka.doPhase(peerPublicKey, true);
-            return ka.generateSecret("TlsPremasterSecret");
-        } catch (GeneralSecurityException e) {
-            throw new RuntimeException("Could not generate secret", e);
-        }
-    }
-
-    // called by ServerHandshaker
-    SecretKey getAgreedSecret(byte[] encodedPoint) {
-        try {
-            ECParameterSpec params = publicKey.getParams();
-            ECPoint point = JsseJce.decodePoint(encodedPoint, params.getCurve());
-            KeyFactory kf = JsseJce.getKeyFactory("EC");
-            ECPublicKeySpec spec = new ECPublicKeySpec(point, params);
-            PublicKey peerPublicKey = kf.generatePublic(spec);
-            return getAgreedSecret(peerPublicKey);
-        } catch (GeneralSecurityException e) {
-            throw new RuntimeException("Could not generate secret", e);
-        } catch (java.io.IOException e) {
-            throw new RuntimeException("Could not generate secret", e);
-        }
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/EngineArgs.java b/ojluni/src/main/java/sun/security/ssl/EngineArgs.java
deleted file mode 100755
index 5f89d0c..0000000
--- a/ojluni/src/main/java/sun/security/ssl/EngineArgs.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.nio.*;
-
-/*
- * A multi-purpose class which handles all of the SSLEngine arguments.
- * It validates arguments, checks for RO conditions, does space
- * calculations, performs scatter/gather, etc.
- *
- * @author Brad R. Wetmore
- */
-class EngineArgs {
-
-    /*
-     * Keep track of the input parameters.
-     */
-    ByteBuffer netData;
-    ByteBuffer [] appData;
-
-    private int offset;         // offset/len for the appData array.
-    private int len;
-
-    /*
-     * The initial pos/limit conditions.  This is useful because we can
-     * quickly calculate the amount consumed/produced in successful
-     * operations, or easily return the buffers to their pre-error
-     * conditions.
-     */
-    private int netPos;
-    private int netLim;
-
-    private int [] appPoss;
-    private int [] appLims;
-
-    /*
-     * Sum total of the space remaining in all of the appData buffers
-     */
-    private int appRemaining = 0;
-
-    private boolean wrapMethod;
-
-    /*
-     * Called by the SSLEngine.wrap() method.
-     */
-    EngineArgs(ByteBuffer [] appData, int offset, int len,
-            ByteBuffer netData) {
-        this.wrapMethod = true;
-        init(netData, appData, offset, len);
-    }
-
-    /*
-     * Called by the SSLEngine.unwrap() method.
-     */
-    EngineArgs(ByteBuffer netData, ByteBuffer [] appData, int offset,
-            int len) {
-        this.wrapMethod = false;
-        init(netData, appData, offset, len);
-    }
-
-    /*
-     * The main initialization method for the arguments.  Most
-     * of them are pretty obvious as to what they do.
-     *
-     * Since we're already iterating over appData array for validity
-     * checking, we also keep track of how much remainging space is
-     * available.  Info is used in both unwrap (to see if there is
-     * enough space available in the destination), and in wrap (to
-     * determine how much more we can copy into the outgoing data
-     * buffer.
-     */
-    private void init(ByteBuffer netData, ByteBuffer [] appData,
-            int offset, int len) {
-
-        if ((netData == null) || (appData == null)) {
-            throw new IllegalArgumentException("src/dst is null");
-        }
-
-        if ((offset < 0) || (len < 0) || (offset > appData.length - len)) {
-            throw new IndexOutOfBoundsException();
-        }
-
-        if (wrapMethod && netData.isReadOnly()) {
-            throw new ReadOnlyBufferException();
-        }
-
-        netPos = netData.position();
-        netLim = netData.limit();
-
-        appPoss = new int [appData.length];
-        appLims = new int [appData.length];
-
-        for (int i = offset; i < offset + len; i++) {
-            if (appData[i] == null) {
-                throw new IllegalArgumentException(
-                    "appData[" + i + "] == null");
-            }
-
-            /*
-             * If we're unwrapping, then check to make sure our
-             * destination bufffers are writable.
-             */
-            if (!wrapMethod && appData[i].isReadOnly()) {
-                throw new ReadOnlyBufferException();
-            }
-
-            appRemaining += appData[i].remaining();
-
-            appPoss[i] = appData[i].position();
-            appLims[i] = appData[i].limit();
-        }
-
-        /*
-         * Ok, looks like we have a good set of args, let's
-         * store the rest of this stuff.
-         */
-        this.netData = netData;
-        this.appData = appData;
-        this.offset = offset;
-        this.len = len;
-    }
-
-    /*
-     * Given spaceLeft bytes to transfer, gather up that much data
-     * from the appData buffers (starting at offset in the array),
-     * and transfer it into the netData buffer.
-     *
-     * The user has already ensured there is enough room.
-     */
-    void gather(int spaceLeft) {
-        for (int i = offset; (i < (offset + len)) && (spaceLeft > 0); i++) {
-            int amount = Math.min(appData[i].remaining(), spaceLeft);
-            appData[i].limit(appData[i].position() + amount);
-            netData.put(appData[i]);
-            appRemaining -= amount;
-            spaceLeft -= amount;
-        }
-    }
-
-    /*
-     * Using the supplied buffer, scatter the data into the appData buffers
-     * (starting at offset in the array).
-     *
-     * The user has already ensured there is enough room.
-     */
-    void scatter(ByteBuffer readyData) {
-        int amountLeft = readyData.remaining();
-
-        for (int i = offset; (i < (offset + len)) && (amountLeft > 0);
-                i++) {
-            int amount = Math.min(appData[i].remaining(), amountLeft);
-            readyData.limit(readyData.position() + amount);
-            appData[i].put(readyData);
-            amountLeft -= amount;
-        }
-        assert(readyData.remaining() == 0);
-    }
-
-    int getAppRemaining() {
-        return appRemaining;
-    }
-
-    /*
-     * Calculate the bytesConsumed/byteProduced.  Aren't you glad
-     * we saved this off earlier?
-     */
-    int deltaNet() {
-        return (netData.position() - netPos);
-    }
-
-    /*
-     * Calculate the bytesConsumed/byteProduced.  Aren't you glad
-     * we saved this off earlier?
-     */
-    int deltaApp() {
-        int sum = 0;    // Only calculating 2^14 here, don't need a long.
-
-        for (int i = offset; i < offset + len; i++) {
-            sum += appData[i].position() - appPoss[i];
-        }
-
-        return sum;
-    }
-
-    /*
-     * In the case of Exception, we want to reset the positions
-     * to appear as though no data has been consumed or produced.
-     *
-     * Currently, this method is only called as we are preparing to
-     * fail out, and thus we don't need to actually recalculate
-     * appRemaining.  If that assumption changes, that variable should
-     * be updated here.
-     */
-    void resetPos() {
-        netData.position(netPos);
-        for (int i = offset; i < offset + len; i++) {
-            // See comment above about recalculating appRemaining.
-            appData[i].position(appPoss[i]);
-        }
-    }
-
-    /*
-     * We are doing lots of ByteBuffer manipulations, in which case
-     * we need to make sure that the limits get set back correctly.
-     * This is one of the last things to get done before returning to
-     * the user.
-     */
-    void resetLim() {
-        netData.limit(netLim);
-        for (int i = offset; i < offset + len; i++) {
-            appData[i].limit(appLims[i]);
-        }
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/EngineInputRecord.java b/ojluni/src/main/java/sun/security/ssl/EngineInputRecord.java
deleted file mode 100755
index fb7b133..0000000
--- a/ojluni/src/main/java/sun/security/ssl/EngineInputRecord.java
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.nio.*;
-import javax.net.ssl.*;
-import javax.crypto.BadPaddingException;
-import sun.misc.HexDumpEncoder;
-
-
-/**
- * Wrapper class around InputRecord.
- *
- * Application data is kept external to the InputRecord,
- * but handshake data (alert/change_cipher_spec/handshake) will
- * be kept internally in the ByteArrayInputStream.
- *
- * @author Brad Wetmore
- */
-final class EngineInputRecord extends InputRecord {
-
-    private SSLEngineImpl engine;
-
-    /*
-     * A dummy ByteBuffer we'll pass back even when the data
-     * is stored internally.  It'll never actually be used.
-     */
-    static private ByteBuffer tmpBB = ByteBuffer.allocate(0);
-
-    /*
-     * Flag to tell whether the last read/parsed data resides
-     * internal in the ByteArrayInputStream, or in the external
-     * buffers.
-     */
-    private boolean internalData;
-
-    EngineInputRecord(SSLEngineImpl engine) {
-        super();
-        this.engine = engine;
-    }
-
-    byte contentType() {
-        if (internalData) {
-            return super.contentType();
-        } else {
-            return ct_application_data;
-        }
-    }
-
-    /*
-     * Check if there is enough inbound data in the ByteBuffer
-     * to make a inbound packet.  Look for both SSLv2 and SSLv3.
-     *
-     * @return -1 if there are not enough bytes to tell (small header),
-     */
-    int bytesInCompletePacket(ByteBuffer buf) throws SSLException {
-
-        /*
-         * SSLv2 length field is in bytes 0/1
-         * SSLv3/TLS length field is in bytes 3/4
-         */
-        if (buf.remaining() < 5) {
-            return -1;
-        }
-
-        int pos = buf.position();
-        byte byteZero = buf.get(pos);
-
-        int len = 0;
-
-        /*
-         * If we have already verified previous packets, we can
-         * ignore the verifications steps, and jump right to the
-         * determination.  Otherwise, try one last hueristic to
-         * see if it's SSL/TLS.
-         */
-        if (formatVerified ||
-                (byteZero == ct_handshake) ||
-                (byteZero == ct_alert)) {
-            /*
-             * Last sanity check that it's not a wild record
-             */
-            ProtocolVersion recordVersion =
-                ProtocolVersion.valueOf(buf.get(pos + 1), buf.get(pos + 2));
-
-            // Check if too old (currently not possible)
-            // or if the major version does not match.
-            // The actual version negotiation is in the handshaker classes
-            if ((recordVersion.v < ProtocolVersion.MIN.v)
-                    || (recordVersion.major > ProtocolVersion.MAX.major)) {
-                throw new SSLException(
-                    "Unsupported record version " + recordVersion);
-            }
-
-            /*
-             * Reasonably sure this is a V3, disable further checks.
-             * We can't do the same in the v2 check below, because
-             * read still needs to parse/handle the v2 clientHello.
-             */
-            formatVerified = true;
-
-            /*
-             * One of the SSLv3/TLS message types.
-             */
-            len = ((buf.get(pos + 3) & 0xff) << 8) +
-                (buf.get(pos + 4) & 0xff) + headerSize;
-
-        } else {
-            /*
-             * Must be SSLv2 or something unknown.
-             * Check if it's short (2 bytes) or
-             * long (3) header.
-             *
-             * Internals can warn about unsupported SSLv2
-             */
-            boolean isShort = ((byteZero & 0x80) != 0);
-
-            if (isShort &&
-                    ((buf.get(pos + 2) == 1) || buf.get(pos + 2) == 4)) {
-
-                ProtocolVersion recordVersion =
-                    ProtocolVersion.valueOf(buf.get(pos + 3), buf.get(pos + 4));
-
-                // Check if too old (currently not possible)
-                // or if the major version does not match.
-                // The actual version negotiation is in the handshaker classes
-                if ((recordVersion.v < ProtocolVersion.MIN.v)
-                        || (recordVersion.major > ProtocolVersion.MAX.major)) {
-
-                    // if it's not SSLv2, we're out of here.
-                    if (recordVersion.v != ProtocolVersion.SSL20Hello.v) {
-                        throw new SSLException(
-                            "Unsupported record version " + recordVersion);
-                    }
-                }
-
-                /*
-                 * Client or Server Hello
-                 */
-                int mask = (isShort ? 0x7f : 0x3f);
-                len = ((byteZero & mask) << 8) + (buf.get(pos + 1) & 0xff) +
-                    (isShort ? 2 : 3);
-
-            } else {
-                // Gobblygook!
-                throw new SSLException(
-                    "Unrecognized SSL message, plaintext connection?");
-            }
-        }
-
-        return len;
-    }
-
-    /*
-     * Pass the data down if it's internally cached, otherwise
-     * do it here.
-     *
-     * If internal data, data is decrypted internally.
-     *
-     * If external data(app), return a new ByteBuffer with data to
-     * process.
-     */
-    ByteBuffer decrypt(MAC signer,
-            CipherBox box, ByteBuffer bb) throws BadPaddingException {
-
-        if (internalData) {
-            decrypt(signer, box);   // MAC is checked during decryption
-            return tmpBB;
-        }
-
-        BadPaddingException reservedBPE = null;
-        int tagLen = signer.MAClen();
-        int cipheredLength = bb.remaining();
-
-        if (!box.isNullCipher()) {
-            // sanity check length of the ciphertext
-            if (!box.sanityCheck(tagLen, cipheredLength)) {
-                throw new BadPaddingException(
-                    "ciphertext sanity check failed");
-            }
-
-            try {
-                // Note that the CipherBox.decrypt() does not change
-                // the capacity of the buffer.
-                box.decrypt(bb, tagLen);
-            } catch (BadPaddingException bpe) {
-                // RFC 2246 states that decryption_failed should be used
-                // for this purpose. However, that allows certain attacks,
-                // so we just send bad record MAC. We also need to make
-                // sure to always check the MAC to avoid a timing attack
-                // for the same issue. See paper by Vaudenay et al and the
-                // update in RFC 4346/5246.
-                //
-                // Failover to message authentication code checking.
-                reservedBPE = bpe;
-            } finally {
-                bb.rewind();
-            }
-        }
-
-        if (tagLen != 0) {
-            int macOffset = bb.limit() - tagLen;
-
-            // Note that although it is not necessary, we run the same MAC
-            // computation and comparison on the payload for both stream
-            // cipher and CBC block cipher.
-            if (bb.remaining() < tagLen) {
-                // negative data length, something is wrong
-                if (reservedBPE == null) {
-                    reservedBPE = new BadPaddingException("bad record");
-                }
-
-                // set offset of the dummy MAC
-                macOffset = cipheredLength - tagLen;
-                bb.limit(cipheredLength);
-            }
-
-            // Run MAC computation and comparison on the payload.
-            if (checkMacTags(contentType(), bb, signer, false)) {
-                if (reservedBPE == null) {
-                    reservedBPE = new BadPaddingException("bad record MAC");
-                }
-            }
-
-            // Run MAC computation and comparison on the remainder.
-            //
-            // It is only necessary for CBC block cipher.  It is used to get a
-            // constant time of MAC computation and comparison on each record.
-            if (box.isCBCMode()) {
-                int remainingLen = calculateRemainingLen(
-                                        signer, cipheredLength, macOffset);
-
-                // NOTE: here we use the InputRecord.buf because I did not find
-                // an effective way to work on ByteBuffer when its capacity is
-                // less than remainingLen.
-
-                // NOTE: remainingLen may be bigger (less than 1 block of the
-                // hash algorithm of the MAC) than the cipheredLength. However,
-                // We won't need to worry about it because we always use a
-                // maximum buffer for every record.  We need a change here if
-                // we use small buffer size in the future.
-                if (remainingLen > buf.length) {
-                    // unlikely to happen, just a placehold
-                    throw new RuntimeException(
-                        "Internal buffer capacity error");
-                }
-
-                // Won't need to worry about the result on the remainder. And
-                // then we won't need to worry about what's actual data to
-                // check MAC tag on.  We start the check from the header of the
-                // buffer so that we don't need to construct a new byte buffer.
-                checkMacTags(contentType(), buf, 0, remainingLen, signer, true);
-            }
-
-            bb.limit(macOffset);
-        }
-
-        // Is it a failover?
-        if (reservedBPE != null) {
-            throw reservedBPE;
-        }
-
-        return bb.slice();
-    }
-
-    /*
-     * Run MAC computation and comparison
-     *
-     * Please DON'T change the content of the ByteBuffer parameter!
-     */
-    private static boolean checkMacTags(byte contentType, ByteBuffer bb,
-            MAC signer, boolean isSimulated) {
-
-        int tagLen = signer.MAClen();
-        int lim = bb.limit();
-        int macData = lim - tagLen;
-
-        bb.limit(macData);
-        byte[] hash = signer.compute(contentType, bb, isSimulated);
-        if (hash == null || tagLen != hash.length) {
-            // Something is wrong with MAC implementation.
-            throw new RuntimeException("Internal MAC error");
-        }
-
-        bb.position(macData);
-        bb.limit(lim);
-        try {
-            int[] results = compareMacTags(bb, hash);
-            return (results[0] != 0);
-        } finally {
-            bb.rewind();
-            bb.limit(macData);
-        }
-    }
-
-    /*
-     * A constant-time comparison of the MAC tags.
-     *
-     * Please DON'T change the content of the ByteBuffer parameter!
-     */
-    private static int[] compareMacTags(ByteBuffer bb, byte[] tag) {
-
-        // An array of hits is used to prevent Hotspot optimization for
-        // the purpose of a constant-time check.
-        int[] results = {0, 0};     // {missed #, matched #}
-
-        // The caller ensures there are enough bytes available in the buffer.
-        // So we won't need to check the remaining of the buffer.
-        for (int i = 0; i < tag.length; i++) {
-            if (bb.get() != tag[i]) {
-                results[0]++;       // mismatched bytes
-            } else {
-                results[1]++;       // matched bytes
-            }
-        }
-
-        return results;
-    }
-
-    /*
-     * Override the actual write below.  We do things this way to be
-     * consistent with InputRecord.  InputRecord may try to write out
-     * data to the peer, and *then* throw an Exception.  This forces
-     * data to be generated/output before the exception is ever
-     * generated.
-     */
-    void writeBuffer(OutputStream s, byte [] buf, int off, int len)
-            throws IOException {
-        /*
-         * Copy data out of buffer, it's ready to go.
-         */
-        ByteBuffer netBB = (ByteBuffer)
-            (ByteBuffer.allocate(len).put(buf, 0, len).flip());
-        engine.writer.putOutboundDataSync(netBB);
-    }
-
-    /*
-     * Delineate or read a complete packet from src.
-     *
-     * If internal data (hs, alert, ccs), the data is read and
-     * stored internally.
-     *
-     * If external data (app), return a new ByteBuffer which points
-     * to the data to process.
-     */
-    ByteBuffer read(ByteBuffer srcBB) throws IOException {
-        /*
-         * Could have a src == null/dst == null check here,
-         * but that was already checked by SSLEngine.unwrap before
-         * ever attempting to read.
-         */
-
-        /*
-         * If we have anything besides application data,
-         * or if we haven't even done the initial v2 verification,
-         * we send this down to be processed by the underlying
-         * internal cache.
-         */
-        if (!formatVerified ||
-                (srcBB.get(srcBB.position()) != ct_application_data)) {
-            internalData = true;
-            read(new ByteBufferInputStream(srcBB), (OutputStream) null);
-            return tmpBB;
-        }
-
-        internalData = false;
-
-        int srcPos = srcBB.position();
-        int srcLim = srcBB.limit();
-
-        ProtocolVersion recordVersion = ProtocolVersion.valueOf(
-                srcBB.get(srcPos + 1), srcBB.get(srcPos + 2));
-        // Check if too old (currently not possible)
-        // or if the major version does not match.
-        // The actual version negotiation is in the handshaker classes
-        if ((recordVersion.v < ProtocolVersion.MIN.v)
-                || (recordVersion.major > ProtocolVersion.MAX.major)) {
-            throw new SSLException(
-                "Unsupported record version " + recordVersion);
-        }
-
-        /*
-         * It's really application data.  How much to consume?
-         * Jump over the header.
-         */
-        int len = bytesInCompletePacket(srcBB);
-        assert(len > 0);
-
-        if (debug != null && Debug.isOn("packet")) {
-            try {
-                HexDumpEncoder hd = new HexDumpEncoder();
-                srcBB.limit(srcPos + len);
-                ByteBuffer bb = srcBB.duplicate();  // Use copy of BB
-
-                System.out.println("[Raw read (bb)]: length = " + len);
-                hd.encodeBuffer(bb, System.out);
-            } catch (IOException e) { }
-        }
-
-        // Demarcate past header to end of packet.
-        srcBB.position(srcPos + headerSize);
-        srcBB.limit(srcPos + len);
-
-        // Protect remainder of buffer, create slice to actually
-        // operate on.
-        ByteBuffer bb = srcBB.slice();
-
-        srcBB.position(srcBB.limit());
-        srcBB.limit(srcLim);
-
-        return bb;
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/EngineOutputRecord.java b/ojluni/src/main/java/sun/security/ssl/EngineOutputRecord.java
deleted file mode 100755
index c7605fd..0000000
--- a/ojluni/src/main/java/sun/security/ssl/EngineOutputRecord.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.nio.*;
-
-import javax.net.ssl.SSLException;
-import sun.misc.HexDumpEncoder;
-
-
-/**
- * A OutputRecord class extension which uses external ByteBuffers
- * or the internal ByteArrayOutputStream for data manipulations.
- * <P>
- * Instead of rewriting this entire class
- * to use ByteBuffers, we leave things intact, so handshake, CCS,
- * and alerts will continue to use the internal buffers, but application
- * data will use external buffers.
- *
- * @author Brad Wetmore
- */
-final class EngineOutputRecord extends OutputRecord {
-
-    private SSLEngineImpl engine;
-    private EngineWriter writer;
-
-    private boolean finishedMsg = false;
-
-    /*
-     * All handshake hashing is done by the superclass
-     */
-
-    /*
-     * Default constructor makes a record supporting the maximum
-     * SSL record size.  It allocates the header bytes directly.
-     *
-     * @param type the content type for the record
-     */
-    EngineOutputRecord(byte type, SSLEngineImpl engine) {
-        super(type, recordSize(type));
-        this.engine = engine;
-        writer = engine.writer;
-    }
-
-    /**
-     * Get the size of the buffer we need for records of the specified
-     * type.
-     * <P>
-     * Application data buffers will provide their own byte buffers,
-     * and will not use the internal byte caching.
-     */
-    private static int recordSize(byte type) {
-        switch (type) {
-
-        case ct_change_cipher_spec:
-        case ct_alert:
-            return maxAlertRecordSize;
-
-        case ct_handshake:
-            return maxRecordSize;
-
-        case ct_application_data:
-            return 0;
-        }
-
-        throw new RuntimeException("Unknown record type: " + type);
-    }
-
-    void setFinishedMsg() {
-        finishedMsg = true;
-    }
-
-    public void flush() throws IOException {
-        finishedMsg = false;
-    }
-
-    boolean isFinishedMsg() {
-        return finishedMsg;
-    }
-
-
-    /**
-     * Calculate the MAC value, storing the result either in
-     * the internal buffer, or at the end of the destination
-     * ByteBuffer.
-     * <P>
-     * We assume that the higher levels have assured us enough
-     * room, otherwise we'll indirectly throw a
-     * BufferOverFlowException runtime exception.
-     *
-     * position should equal limit, and points to the next
-     * free spot.
-     */
-    private void addMAC(MAC signer, ByteBuffer bb)
-            throws IOException {
-
-        if (signer.MAClen() != 0) {
-            byte[] hash = signer.compute(contentType(), bb, false);
-
-            /*
-             * position was advanced to limit in compute above.
-             *
-             * Mark next area as writable (above layers should have
-             * established that we have plenty of room), then write
-             * out the hash.
-             */
-            bb.limit(bb.limit() + hash.length);
-            bb.put(hash);
-        }
-    }
-
-    /*
-     * Encrypt a ByteBuffer.
-     *
-     * We assume that the higher levels have assured us enough
-     * room for the encryption (plus padding), otherwise we'll
-     * indirectly throw a BufferOverFlowException runtime exception.
-     *
-     * position and limit will be the same, and points to the
-     * next free spot.
-     */
-    void encrypt(CipherBox box, ByteBuffer bb) {
-        box.encrypt(bb);
-    }
-
-    /*
-     * Override the actual write below.  We do things this way to be
-     * consistent with InputRecord.  InputRecord may try to write out
-     * data to the peer, and *then* throw an Exception.  This forces
-     * data to be generated/output before the exception is ever
-     * generated.
-     */
-    @Override
-    void writeBuffer(OutputStream s, byte [] buf, int off, int len,
-            int debugOffset) throws IOException {
-        /*
-         * Copy data out of buffer, it's ready to go.
-         */
-        ByteBuffer netBB = (ByteBuffer)
-            ByteBuffer.allocate(len).put(buf, 0, len).flip();
-        writer.putOutboundData(netBB);
-    }
-
-    /*
-     * Main method for writing non-application data.
-     * We MAC/encrypt, then send down for processing.
-     */
-    void write(MAC writeMAC, CipherBox writeCipher) throws IOException {
-        /*
-         * Sanity check.
-         */
-        switch (contentType()) {
-        case ct_change_cipher_spec:
-        case ct_alert:
-        case ct_handshake:
-            break;
-        default:
-            throw new RuntimeException("unexpected byte buffers");
-        }
-
-        /*
-         * Don't bother to really write empty records.  We went this
-         * far to drive the handshake machinery, for correctness; not
-         * writing empty records improves performance by cutting CPU
-         * time and network resource usage.  Also, some protocol
-         * implementations are fragile and don't like to see empty
-         * records, so this increases robustness.
-         *
-         * (Even change cipher spec messages have a byte of data!)
-         */
-        if (!isEmpty()) {
-            // compress();              // eventually
-            addMAC(writeMAC);
-            encrypt(writeCipher);
-            write((OutputStream)null, false,   // send down for processing
-                (ByteArrayOutputStream)null);
-        }
-        return;
-    }
-
-    /**
-     * Main wrap/write driver.
-     */
-    void write(EngineArgs ea, MAC writeMAC, CipherBox writeCipher)
-            throws IOException {
-        /*
-         * sanity check to make sure someone didn't inadvertantly
-         * send us an impossible combination we don't know how
-         * to process.
-         */
-        assert(contentType() == ct_application_data);
-
-        /*
-         * Have we set the MAC's yet?  If not, we're not ready
-         * to process application data yet.
-         */
-        if (writeMAC == MAC.NULL) {
-            return;
-        }
-
-        /*
-         * Don't bother to really write empty records.  We went this
-         * far to drive the handshake machinery, for correctness; not
-         * writing empty records improves performance by cutting CPU
-         * time and network resource usage.  Also, some protocol
-         * implementations are fragile and don't like to see empty
-         * records, so this increases robustness.
-         */
-        if (ea.getAppRemaining() == 0) {
-            return;
-        }
-
-        /*
-         * By default, we counter chosen plaintext issues on CBC mode
-         * ciphersuites in SSLv3/TLS1.0 by sending one byte of application
-         * data in the first record of every payload, and the rest in
-         * subsequent record(s). Note that the issues have been solved in
-         * TLS 1.1 or later.
-         *
-         * It is not necessary to split the very first application record of
-         * a freshly negotiated TLS session, as there is no previous
-         * application data to guess.  To improve compatibility, we will not
-         * split such records.
-         *
-         * Because of the compatibility, we'd better produce no more than
-         * SSLSession.getPacketBufferSize() net data for each wrap. As we
-         * need a one-byte record at first, the 2nd record size should be
-         * equal to or less than Record.maxDataSizeMinusOneByteRecord.
-         *
-         * This avoids issues in the outbound direction.  For a full fix,
-         * the peer must have similar protections.
-         */
-        int length;
-        if (engine.needToSplitPayload(writeCipher, protocolVersion)) {
-            write(ea, writeMAC, writeCipher, 0x01);
-            ea.resetLim();      // reset application data buffer limit
-            length = Math.min(ea.getAppRemaining(),
-                        maxDataSizeMinusOneByteRecord);
-        } else {
-            length = Math.min(ea.getAppRemaining(), maxDataSize);
-        }
-
-        // Don't bother to really write empty records.
-        if (length > 0) {
-            write(ea, writeMAC, writeCipher, length);
-        }
-
-        return;
-    }
-
-    void write(EngineArgs ea, MAC writeMAC, CipherBox writeCipher,
-            int length) throws IOException {
-        /*
-         * Copy out existing buffer values.
-         */
-        ByteBuffer dstBB = ea.netData;
-        int dstPos = dstBB.position();
-        int dstLim = dstBB.limit();
-
-        /*
-         * Where to put the data.  Jump over the header.
-         *
-         * Don't need to worry about SSLv2 rewrites, if we're here,
-         * that's long since done.
-         */
-        int dstData = dstPos + headerSize;
-        dstBB.position(dstData);
-
-        ea.gather(length);
-
-        /*
-         * "flip" but skip over header again, add MAC & encrypt
-         * addMAC will expand the limit to reflect the new
-         * data.
-         */
-        dstBB.limit(dstBB.position());
-        dstBB.position(dstData);
-        addMAC(writeMAC, dstBB);
-
-        /*
-         * Encrypt may pad, so again the limit may have changed.
-         */
-        dstBB.limit(dstBB.position());
-        dstBB.position(dstData);
-        encrypt(writeCipher, dstBB);
-
-        if (debug != null
-                && (Debug.isOn("record") || Debug.isOn("handshake"))) {
-            if ((debug != null && Debug.isOn("record"))
-                    || contentType() == ct_change_cipher_spec)
-                System.out.println(Thread.currentThread().getName()
-                    // v3.0/v3.1 ...
-                    + ", WRITE: " + protocolVersion
-                    + " " + InputRecord.contentName(contentType())
-                    + ", length = " + length);
-        }
-
-        int packetLength = dstBB.limit() - dstData;
-
-        /*
-         * Finish out the record header.
-         */
-        dstBB.put(dstPos, contentType());
-        dstBB.put(dstPos + 1, protocolVersion.major);
-        dstBB.put(dstPos + 2, protocolVersion.minor);
-        dstBB.put(dstPos + 3, (byte)(packetLength >> 8));
-        dstBB.put(dstPos + 4, (byte)packetLength);
-
-        /*
-         * Position was already set by encrypt() above.
-         */
-        dstBB.limit(dstLim);
-
-        return;
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/EngineWriter.java b/ojluni/src/main/java/sun/security/ssl/EngineWriter.java
deleted file mode 100755
index c930af7..0000000
--- a/ojluni/src/main/java/sun/security/ssl/EngineWriter.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import javax.net.ssl.*;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.LinkedList;
-import javax.net.ssl.SSLEngineResult.HandshakeStatus;
-import sun.misc.HexDumpEncoder;
-
-/**
- * A class to help abstract away SSLEngine writing synchronization.
- */
-final class EngineWriter {
-
-    /*
-     * Outgoing handshake Data waiting for a ride is stored here.
-     * Normal application data is written directly into the outbound
-     * buffer, but handshake data can be written out at any time,
-     * so we have buffer it somewhere.
-     *
-     * When wrap is called, we first check to see if there is
-     * any data waiting, then if we're in a data transfer state,
-     * we try to write app data.
-     *
-     * This will contain either ByteBuffers, or the marker
-     * HandshakeStatus.FINISHED to signify that a handshake just completed.
-     */
-    private LinkedList<Object> outboundList;
-
-    private boolean outboundClosed = false;
-
-    /* Class and subclass dynamic debugging support */
-    private static final Debug debug = Debug.getInstance("ssl");
-
-    EngineWriter() {
-        outboundList = new LinkedList<Object>();
-    }
-
-    /*
-     * Upper levels assured us we had room for at least one packet of data.
-     * As per the SSLEngine spec, we only return one SSL packets worth of
-     * data.
-     */
-    private HandshakeStatus getOutboundData(ByteBuffer dstBB) {
-
-        Object msg = outboundList.removeFirst();
-        assert(msg instanceof ByteBuffer);
-
-        ByteBuffer bbIn = (ByteBuffer) msg;
-        assert(dstBB.remaining() >= bbIn.remaining());
-
-        dstBB.put(bbIn);
-
-        /*
-         * If we have more data in the queue, it's either
-         * a finished message, or an indication that we need
-         * to call wrap again.
-         */
-        if (hasOutboundDataInternal()) {
-            msg = outboundList.getFirst();
-            if (msg == HandshakeStatus.FINISHED) {
-                outboundList.removeFirst();     // consume the message
-                return HandshakeStatus.FINISHED;
-            } else {
-                return HandshakeStatus.NEED_WRAP;
-            }
-        } else {
-            return null;
-        }
-    }
-
-    /*
-     * Properly orders the output of the data written to the wrap call.
-     * This is only handshake data, application data goes through the
-     * other writeRecord.
-     */
-    synchronized void writeRecord(EngineOutputRecord outputRecord,
-            MAC writeMAC, CipherBox writeCipher) throws IOException {
-
-        /*
-         * Only output if we're still open.
-         */
-        if (outboundClosed) {
-            throw new IOException("writer side was already closed.");
-        }
-
-        outputRecord.write(writeMAC, writeCipher);
-
-        /*
-         * Did our handshakers notify that we just sent the
-         * Finished message?
-         *
-         * Add an "I'm finished" message to the queue.
-         */
-        if (outputRecord.isFinishedMsg()) {
-            outboundList.addLast(HandshakeStatus.FINISHED);
-        }
-    }
-
-    /*
-     * Output the packet info.
-     */
-    private void dumpPacket(EngineArgs ea, boolean hsData) {
-        try {
-            HexDumpEncoder hd = new HexDumpEncoder();
-
-            ByteBuffer bb = ea.netData.duplicate();
-
-            int pos = bb.position();
-            bb.position(pos - ea.deltaNet());
-            bb.limit(pos);
-
-            System.out.println("[Raw write" +
-                (hsData ? "" : " (bb)") + "]: length = " +
-                bb.remaining());
-            hd.encodeBuffer(bb, System.out);
-        } catch (IOException e) { }
-    }
-
-    /*
-     * Properly orders the output of the data written to the wrap call.
-     * Only app data goes through here, handshake data goes through
-     * the other writeRecord.
-     *
-     * Shouldn't expect to have an IOException here.
-     *
-     * Return any determined status.
-     */
-    synchronized HandshakeStatus writeRecord(
-            EngineOutputRecord outputRecord, EngineArgs ea, MAC writeMAC,
-            CipherBox writeCipher) throws IOException {
-
-        /*
-         * If we have data ready to go, output this first before
-         * trying to consume app data.
-         */
-        if (hasOutboundDataInternal()) {
-            HandshakeStatus hss = getOutboundData(ea.netData);
-
-            if (debug != null && Debug.isOn("packet")) {
-                /*
-                 * We could have put the dump in
-                 * OutputRecord.write(OutputStream), but let's actually
-                 * output when it's actually output by the SSLEngine.
-                 */
-                dumpPacket(ea, true);
-            }
-
-            return hss;
-        }
-
-        /*
-         * If we are closed, no more app data can be output.
-         * Only existing handshake data (above) can be obtained.
-         */
-        if (outboundClosed) {
-            throw new IOException("The write side was already closed");
-        }
-
-        outputRecord.write(ea, writeMAC, writeCipher);
-
-        if (debug != null && Debug.isOn("packet")) {
-            dumpPacket(ea, false);
-        }
-
-        /*
-         * No way new outbound handshake data got here if we're
-         * locked properly.
-         *
-         * We don't have any status we can return.
-         */
-        return null;
-    }
-
-    /*
-     * We already hold "this" lock, this is the callback from the
-     * outputRecord.write() above.  We already know this
-     * writer can accept more data (outboundClosed == false),
-     * and the closure is sync'd.
-     */
-    void putOutboundData(ByteBuffer bytes) {
-        outboundList.addLast(bytes);
-    }
-
-    /*
-     * This is for the really rare case that someone is writing from
-     * the *InputRecord* before we know what to do with it.
-     */
-    synchronized void putOutboundDataSync(ByteBuffer bytes)
-            throws IOException {
-
-        if (outboundClosed) {
-            throw new IOException("Write side already closed");
-        }
-
-        outboundList.addLast(bytes);
-    }
-
-    /*
-     * Non-synch'd version of this method, called by internals
-     */
-    private boolean hasOutboundDataInternal() {
-        return (outboundList.size() != 0);
-    }
-
-    synchronized boolean hasOutboundData() {
-        return hasOutboundDataInternal();
-    }
-
-    synchronized boolean isOutboundDone() {
-        return outboundClosed && !hasOutboundDataInternal();
-    }
-
-    synchronized void closeOutbound() {
-        outboundClosed = true;
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/EphemeralKeyManager.java b/ojluni/src/main/java/sun/security/ssl/EphemeralKeyManager.java
deleted file mode 100755
index 47dba95..0000000
--- a/ojluni/src/main/java/sun/security/ssl/EphemeralKeyManager.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.security.*;
-
-/**
- * The "KeyManager" for ephemeral RSA keys. Ephemeral DH and ECDH keys
- * are handled by the DHCrypt and ECDHCrypt classes, respectively.
- *
- * @author  Andreas Sterbenz
- */
-final class EphemeralKeyManager {
-
-    // indices for the keys array below
-    private final static int INDEX_RSA512 = 0;
-    private final static int INDEX_RSA1024 = 1;
-
-    /*
-     * Current cached RSA KeyPairs. Elements are never null.
-     * Indexed via the the constants above.
-     */
-    private final EphemeralKeyPair[] keys = new EphemeralKeyPair[] {
-        new EphemeralKeyPair(null),
-        new EphemeralKeyPair(null),
-    };
-
-    EphemeralKeyManager() {
-        // empty
-    }
-
-    /*
-     * Get a temporary RSA KeyPair.
-     */
-    KeyPair getRSAKeyPair(boolean export, SecureRandom random) {
-        int length, index;
-        if (export) {
-            length = 512;
-            index = INDEX_RSA512;
-        } else {
-            length = 1024;
-            index = INDEX_RSA1024;
-        }
-
-        synchronized (keys) {
-            KeyPair kp = keys[index].getKeyPair();
-            if (kp == null) {
-                try {
-                    KeyPairGenerator kgen = JsseJce.getKeyPairGenerator("RSA");
-                    kgen.initialize(length, random);
-                    keys[index] = new EphemeralKeyPair(kgen.genKeyPair());
-                    kp = keys[index].getKeyPair();
-                } catch (Exception e) {
-                    // ignore
-                }
-            }
-            return kp;
-        }
-    }
-
-    /**
-     * Inner class to handle storage of ephemeral KeyPairs.
-     */
-    private static class EphemeralKeyPair {
-
-        // maximum number of times a KeyPair is used
-        private final static int MAX_USE = 200;
-
-        // maximum time interval in which the keypair is used (1 hour in ms)
-        private final static long USE_INTERVAL = 3600*1000;
-
-        private KeyPair keyPair;
-        private int uses;
-        private long expirationTime;
-
-        private EphemeralKeyPair(KeyPair keyPair) {
-            this.keyPair = keyPair;
-            expirationTime = System.currentTimeMillis() + USE_INTERVAL;
-        }
-
-        /*
-         * Check if the KeyPair can still be used.
-         */
-        private boolean isValid() {
-            return (keyPair != null) && (uses < MAX_USE)
-                   && (System.currentTimeMillis() < expirationTime);
-        }
-
-        /*
-         * Return the KeyPair or null if it is invalid.
-         */
-        private KeyPair getKeyPair() {
-            if (isValid() == false) {
-                keyPair = null;
-                return null;
-            }
-            uses++;
-            return keyPair;
-        }
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/HandshakeHash.java b/ojluni/src/main/java/sun/security/ssl/HandshakeHash.java
deleted file mode 100755
index ffb8f32..0000000
--- a/ojluni/src/main/java/sun/security/ssl/HandshakeHash.java
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.ByteArrayOutputStream;
-import java.security.*;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-
-/**
- * Abstraction for the SSL/TLS hash of all handshake messages that is
- * maintained to verify the integrity of the negotiation. Internally,
- * it consists of an MD5 and an SHA1 digest. They are used in the client
- * and server finished messages and in certificate verify messages (if sent).
- *
- * This class transparently deals with cloneable and non-cloneable digests.
- *
- * This class now supports TLS 1.2 also. The key difference for TLS 1.2
- * is that you cannot determine the hash algorithms for CertificateVerify
- * at a early stage. On the other hand, it's simpler than TLS 1.1 (and earlier)
- * that there is no messy MD5+SHA1 digests.
- *
- * You need to obey these conventions when using this class:
- *
- * 1. protocolDetermined(version) should be called when the negotiated
- * protocol version is determined.
- *
- * 2. Before protocolDetermined() is called, only update(), reset(),
- * restrictCertificateVerifyAlgs(), setFinishedAlg(), and
- * setCertificateVerifyAlg() can be called.
- *
- * 3. After protocolDetermined() is called, reset() cannot be called.
- *
- * 4. After protocolDetermined() is called, if the version is pre-TLS 1.2,
- * getFinishedHash() and getCertificateVerifyHash() cannot be called. Otherwise,
- * getMD5Clone() and getSHAClone() cannot be called.
- *
- * 5. getMD5Clone() and getSHAClone() can only be called after
- * protocolDetermined() is called and version is pre-TLS 1.2.
- *
- * 6. getFinishedHash() and getCertificateVerifyHash() can only be called after
- * all protocolDetermined(), setCertificateVerifyAlg() and setFinishedAlg()
- * have been called and the version is TLS 1.2. If a CertificateVerify message
- * is to be used, call setCertificateVerifyAlg() with the hash algorithm as the
- * argument. Otherwise, you still must call setCertificateVerifyAlg(null) before
- * calculating any hash value.
- *
- * Suggestions: Call protocolDetermined(), restrictCertificateVerifyAlgs(),
- * setFinishedAlg(), and setCertificateVerifyAlg() as early as possible.
- *
- * Example:
- * <pre>
- * HandshakeHash hh = new HandshakeHash(...)
- * hh.protocolDetermined(ProtocolVersion.TLS12);
- * hh.update(clientHelloBytes);
- * hh.setFinishedAlg("SHA-256");
- * hh.update(serverHelloBytes);
- * ...
- * hh.setCertificateVerifyAlg("SHA-384");
- * hh.update(CertificateVerifyBytes);
- * byte[] cvDigest = hh.getCertificateVerifyHash();
- * ...
- * hh.update(finished1);
- * byte[] finDigest1 = hh.getFinishedHash();
- * hh.update(finished2);
- * byte[] finDigest2 = hh.getFinishedHash();
- * </pre>
- * If no CertificateVerify message is to be used, call
- * <pre>
- * hh.setCertificateVerifyAlg(null);
- * </pre>
- * This call can be made once you are certain that this message
- * will never be used.
- */
-final class HandshakeHash {
-
-    // Common
-
-    // -1:  unknown
-    //  1:  <=TLS 1.1
-    //  2:  TLS 1.2
-    private int version = -1;
-    private ByteArrayOutputStream data = new ByteArrayOutputStream();
-    private final boolean isServer;
-
-    // For TLS 1.1
-    private MessageDigest md5, sha;
-    private final int clonesNeeded;    // needs to be saved for later use
-
-    // For TLS 1.2
-    // cvAlgDetermined == true means setCertificateVerifyAlg() is called
-    private boolean cvAlgDetermined = false;
-    private String cvAlg;
-    private MessageDigest finMD;
-
-    /**
-     * Create a new HandshakeHash. needCertificateVerify indicates whether
-     * a hash for the certificate verify message is required. The argument
-     * algs is a set of all possible hash algorithms that might be used in
-     * TLS 1.2. If the caller is sure that TLS 1.2 won't be used or no
-     * CertificateVerify message will be used, leave it null or empty.
-     */
-    HandshakeHash(boolean isServer, boolean needCertificateVerify,
-            Set<String> algs) {
-        this.isServer = isServer;
-        clonesNeeded = needCertificateVerify ? 3 : 2;
-    }
-
-    void update(byte[] b, int offset, int len) {
-        switch (version) {
-            case 1:
-                md5.update(b, offset, len);
-                sha.update(b, offset, len);
-                break;
-            default:
-                if (finMD != null) {
-                    finMD.update(b, offset, len);
-                }
-                data.write(b, offset, len);
-                break;
-        }
-    }
-
-    /**
-     * Reset the remaining digests. Note this does *not* reset the number of
-     * digest clones that can be obtained. Digests that have already been
-     * cloned and are gone remain gone.
-     */
-    void reset() {
-        if (version != -1) {
-            throw new RuntimeException(
-                    "reset() can be only be called before protocolDetermined");
-        }
-        data.reset();
-    }
-
-
-    void protocolDetermined(ProtocolVersion pv) {
-
-        // Do not set again, will ignore
-        if (version != -1) return;
-
-        version = pv.compareTo(ProtocolVersion.TLS12) >= 0 ? 2 : 1;
-        switch (version) {
-            case 1:
-                // initiate md5, sha and call update on saved array
-                try {
-                    md5 = CloneableDigest.getDigest("MD5", clonesNeeded);
-                    sha = CloneableDigest.getDigest("SHA", clonesNeeded);
-                } catch (NoSuchAlgorithmException e) {
-                    throw new RuntimeException
-                                ("Algorithm MD5 or SHA not available", e);
-                }
-                byte[] bytes = data.toByteArray();
-                update(bytes, 0, bytes.length);
-                break;
-            case 2:
-                break;
-        }
-    }
-
-    /////////////////////////////////////////////////////////////
-    // Below are old methods for pre-TLS 1.1
-    /////////////////////////////////////////////////////////////
-
-    /**
-     * Return a new MD5 digest updated with all data hashed so far.
-     */
-    MessageDigest getMD5Clone() {
-        if (version != 1) {
-            throw new RuntimeException(
-                    "getMD5Clone() can be only be called for TLS 1.1");
-        }
-        return cloneDigest(md5);
-    }
-
-    /**
-     * Return a new SHA digest updated with all data hashed so far.
-     */
-    MessageDigest getSHAClone() {
-        if (version != 1) {
-            throw new RuntimeException(
-                    "getSHAClone() can be only be called for TLS 1.1");
-        }
-        return cloneDigest(sha);
-    }
-
-    private static MessageDigest cloneDigest(MessageDigest digest) {
-        try {
-            return (MessageDigest)digest.clone();
-        } catch (CloneNotSupportedException e) {
-            // cannot occur for digests generated via CloneableDigest
-            throw new RuntimeException("Could not clone digest", e);
-        }
-    }
-
-    /////////////////////////////////////////////////////////////
-    // Below are new methods for TLS 1.2
-    /////////////////////////////////////////////////////////////
-
-    private static String normalizeAlgName(String alg) {
-        alg = alg.toUpperCase(Locale.US);
-        if (alg.startsWith("SHA")) {
-            if (alg.length() == 3) {
-                return "SHA-1";
-            }
-            if (alg.charAt(3) != '-') {
-                return "SHA-" + alg.substring(3);
-            }
-        }
-        return alg;
-    }
-    /**
-     * Specifies the hash algorithm used in Finished. This should be called
-     * based in info in ServerHello.
-     * Can be called multiple times.
-     */
-    void setFinishedAlg(String s) {
-        if (s == null) {
-            throw new RuntimeException(
-                    "setFinishedAlg's argument cannot be null");
-        }
-
-        // Can be called multiple times, but only set once
-        if (finMD != null) return;
-
-        try {
-            finMD = CloneableDigest.getDigest(normalizeAlgName(s), 2);
-        } catch (NoSuchAlgorithmException e) {
-            throw new Error(e);
-        }
-        finMD.update(data.toByteArray());
-    }
-
-    /**
-     * Restricts the possible algorithms for the CertificateVerify. Called by
-     * the server based on info in CertRequest. The argument must be a subset
-     * of the argument with the same name in the constructor. The method can be
-     * called multiple times. If the caller is sure that no CertificateVerify
-     * message will be used, leave this argument null or empty.
-     */
-    void restrictCertificateVerifyAlgs(Set<String> algs) {
-        if (version == 1) {
-            throw new RuntimeException(
-                    "setCertificateVerifyAlg() cannot be called for TLS 1.1");
-        }
-        // Not used yet
-    }
-
-    /**
-     * Specifies the hash algorithm used in CertificateVerify.
-     * Can be called multiple times.
-     */
-    void setCertificateVerifyAlg(String s) {
-
-        // Can be called multiple times, but only set once
-        if (cvAlgDetermined) return;
-
-        cvAlg = s == null ? null : normalizeAlgName(s);
-        cvAlgDetermined = true;
-    }
-
-    byte[] getAllHandshakeMessages() {
-        return data.toByteArray();
-    }
-
-    /**
-     * Calculates the hash in the CertificateVerify. Must be called right
-     * after setCertificateVerifyAlg()
-     */
-    /*byte[] getCertificateVerifyHash() {
-        throw new Error("Do not call getCertificateVerifyHash()");
-    }*/
-
-    /**
-     * Calculates the hash in Finished. Must be called after setFinishedAlg().
-     * This method can be called twice, for Finished messages of the server
-     * side and client side respectively.
-     */
-    byte[] getFinishedHash() {
-        try {
-            return cloneDigest(finMD).digest();
-        } catch (Exception e) {
-            throw new Error("BAD");
-        }
-    }
-}
-
-/**
- * A wrapper for MessageDigests that simulates cloning of non-cloneable
- * digests. It uses the standard MessageDigest API and therefore can be used
- * transparently in place of a regular digest.
- *
- * Note that we extend the MessageDigest class directly rather than
- * MessageDigestSpi. This works because MessageDigest was originally designed
- * this way in the JDK 1.1 days which allows us to avoid creating an internal
- * provider.
- *
- * It can be "cloned" a limited number of times, which is specified at
- * construction time. This is achieved by internally maintaining n digests
- * in parallel. Consequently, it is only 1/n-th times as fast as the original
- * digest.
- *
- * Example:
- *   MessageDigest md = CloneableDigest.getDigest("SHA", 2);
- *   md.update(data1);
- *   MessageDigest md2 = (MessageDigest)md.clone();
- *   md2.update(data2);
- *   byte[] d1 = md2.digest(); // digest of data1 || data2
- *   md.update(data3);
- *   byte[] d2 = md.digest();  // digest of data1 || data3
- *
- * This class is not thread safe.
- *
- */
-final class CloneableDigest extends MessageDigest implements Cloneable {
-
-    /**
-     * The individual MessageDigests. Initially, all elements are non-null.
-     * When clone() is called, the non-null element with the maximum index is
-     * returned and the array element set to null.
-     *
-     * All non-null element are always in the same state.
-     */
-    private final MessageDigest[] digests;
-
-    private CloneableDigest(MessageDigest digest, int n, String algorithm)
-            throws NoSuchAlgorithmException {
-        super(algorithm);
-        digests = new MessageDigest[n];
-        digests[0] = digest;
-        for (int i = 1; i < n; i++) {
-            digests[i] = JsseJce.getMessageDigest(algorithm);
-        }
-    }
-
-    /**
-     * Return a MessageDigest for the given algorithm that can be cloned the
-     * specified number of times. If the default implementation supports
-     * cloning, it is returned. Otherwise, an instance of this class is
-     * returned.
-     */
-    static MessageDigest getDigest(String algorithm, int n)
-            throws NoSuchAlgorithmException {
-        MessageDigest digest = JsseJce.getMessageDigest(algorithm);
-        try {
-            digest.clone();
-            // already cloneable, use it
-            return digest;
-        } catch (CloneNotSupportedException e) {
-            return new CloneableDigest(digest, n, algorithm);
-        }
-    }
-
-    /**
-     * Check if this object is still usable. If it has already been cloned the
-     * maximum number of times, there are no digests left and this object can no
-     * longer be used.
-     */
-    private void checkState() {
-        // XXX handshaking currently doesn't stop updating hashes...
-        // if (digests[0] == null) {
-        //     throw new IllegalStateException("no digests left");
-        // }
-    }
-
-    protected int engineGetDigestLength() {
-        checkState();
-        return digests[0].getDigestLength();
-    }
-
-    protected void engineUpdate(byte b) {
-        checkState();
-        for (int i = 0; (i < digests.length) && (digests[i] != null); i++) {
-            digests[i].update(b);
-        }
-    }
-
-    protected void engineUpdate(byte[] b, int offset, int len) {
-        checkState();
-        for (int i = 0; (i < digests.length) && (digests[i] != null); i++) {
-            digests[i].update(b, offset, len);
-        }
-    }
-
-    protected byte[] engineDigest() {
-        checkState();
-        byte[] digest = digests[0].digest();
-        digestReset();
-        return digest;
-    }
-
-    protected int engineDigest(byte[] buf, int offset, int len)
-            throws DigestException {
-        checkState();
-        int n = digests[0].digest(buf, offset, len);
-        digestReset();
-        return n;
-    }
-
-    /**
-     * Reset all digests after a digest() call. digests[0] has already been
-     * implicitly reset by the digest() call and does not need to be reset
-     * again.
-     */
-    private void digestReset() {
-        for (int i = 1; (i < digests.length) && (digests[i] != null); i++) {
-            digests[i].reset();
-        }
-    }
-
-    protected void engineReset() {
-        checkState();
-        for (int i = 0; (i < digests.length) && (digests[i] != null); i++) {
-            digests[i].reset();
-        }
-    }
-
-    public Object clone() {
-        checkState();
-        for (int i = digests.length - 1; i >= 0; i--) {
-            if (digests[i] != null) {
-                MessageDigest digest = digests[i];
-                digests[i] = null;
-                return digest;
-            }
-        }
-        // cannot occur
-        throw new InternalError();
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/HandshakeInStream.java b/ojluni/src/main/java/sun/security/ssl/HandshakeInStream.java
deleted file mode 100755
index 81c8464..0000000
--- a/ojluni/src/main/java/sun/security/ssl/HandshakeInStream.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.security.MessageDigest;
-
-import javax.net.ssl.SSLException;
-
-/**
- * InputStream for handshake data, used internally only. Contains the
- * handshake message buffer and methods to parse them.
- *
- * Once a new handshake record arrives, it is buffered in this class until
- * processed by the Handshaker. The buffer may also contain incomplete
- * handshake messages in case the message is split across multiple records.
- * Handshaker.process_record deals with all that. It may also contain
- * handshake messages larger than the default buffer size (e.g. large
- * certificate messages). The buffer is grown dynamically to handle that
- * (see InputRecord.queueHandshake()).
- *
- * Note that the InputRecord used as a buffer here is separate from the
- * AppInStream.r, which is where data from the socket is initially read
- * into. This is because once the initial handshake has been completed,
- * handshake and application data messages may be interleaved arbitrarily
- * and must be processed independently.
- *
- * @author David Brownell
- */
-public class HandshakeInStream extends InputStream {
-
-    InputRecord r;
-
-    /*
-     * Construct the stream; we'll be accumulating hashes of the
-     * input records using two sets of digests.
-     */
-    HandshakeInStream(HandshakeHash handshakeHash) {
-        r = new InputRecord();
-        r.setHandshakeHash(handshakeHash);
-    }
-
-
-    // overridden InputStream methods
-
-    /*
-     * Return the number of bytes available for read().
-     *
-     * Note that this returns the bytes remaining in the buffer, not
-     * the bytes remaining in the current handshake message.
-     */
-    public int available() {
-        return r.available();
-    }
-
-    /*
-     * Get a byte of handshake data.
-     */
-    public int read() throws IOException {
-        int n = r.read();
-        if (n == -1) {
-            throw new SSLException("Unexpected end of handshake data");
-        }
-        return n;
-    }
-
-    /*
-     * Get a bunch of bytes of handshake data.
-     */
-    public int read(byte b [], int off, int len) throws IOException {
-        // we read from a ByteArrayInputStream, it always returns the
-        // data in a single read if enough is available
-        int n = r.read(b, off, len);
-        if (n != len) {
-            throw new SSLException("Unexpected end of handshake data");
-        }
-        return n;
-    }
-
-    /*
-     * Skip some handshake data.
-     */
-    public long skip(long n) throws IOException {
-        return r.skip(n);
-    }
-
-    /*
-     * Mark/ reset code, implemented using InputRecord mark/ reset.
-     *
-     * Note that it currently provides only a limited mark functionality
-     * and should be used with care (once a new handshake record has been
-     * read, data that has already been consumed is lost even if marked).
-     */
-
-    public void mark(int readlimit) {
-        r.mark(readlimit);
-    }
-
-    public void reset() {
-        r.reset();
-    }
-
-    public boolean markSupported() {
-        return true;
-    }
-
-
-    // handshake management functions
-
-    /*
-     * Here's an incoming record with handshake data.  Queue the contents;
-     * it might be one or more entire messages, complete a message that's
-     * partly queued, or both.
-     */
-    void incomingRecord(InputRecord in) throws IOException {
-        r.queueHandshake(in);
-    }
-
-    /*
-     * Hash any data we've consumed but not yet hashed.  Useful mostly
-     * for processing client certificate messages (so we can check the
-     * immediately following cert verify message) and finished messages
-     * (so we can compute our own finished message).
-     */
-    void digestNow() {
-        r.doHashes();
-    }
-
-    /*
-     * Do more than skip that handshake data ... totally ignore it.
-     * The difference is that the data does not get hashed.
-     */
-    void ignore(int n) {
-        r.ignore(n);
-    }
-
-
-    // Message parsing methods
-
-    /*
-     * Read 8, 16, 24, and 32 bit SSL integer data types, encoded
-     * in standard big-endian form.
-     */
-
-    int getInt8() throws IOException {
-        return read();
-    }
-
-    int getInt16() throws IOException {
-        return (getInt8() << 8) | getInt8();
-    }
-
-    int getInt24() throws IOException {
-        return (getInt8() << 16) | (getInt8() << 8) | getInt8();
-    }
-
-    int getInt32() throws IOException {
-        return (getInt8() << 24) | (getInt8() << 16)
-             | (getInt8() << 8) | getInt8();
-    }
-
-    /*
-     * Read byte vectors with 8, 16, and 24 bit length encodings.
-     */
-
-    byte[] getBytes8() throws IOException {
-        int len = getInt8();
-        verifyLength(len);
-        byte b[] = new byte[len];
-
-        read(b, 0, len);
-        return b;
-    }
-
-    public byte[] getBytes16() throws IOException {
-        int len = getInt16();
-        verifyLength(len);
-        byte b[] = new byte[len];
-
-        read(b, 0, len);
-        return b;
-    }
-
-    byte[] getBytes24() throws IOException {
-        int len = getInt24();
-        verifyLength(len);
-        byte b[] = new byte[len];
-
-        read(b, 0, len);
-        return b;
-    }
-
-    // Is a length greater than available bytes in the record?
-    private void verifyLength(int len) throws SSLException {
-        if (len > available()) {
-            throw new SSLException(
-                        "Not enough data to fill declared vector size");
-        }
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/HandshakeMessage.java b/ojluni/src/main/java/sun/security/ssl/HandshakeMessage.java
deleted file mode 100755
index 1c85a03..0000000
--- a/ojluni/src/main/java/sun/security/ssl/HandshakeMessage.java
+++ /dev/null
@@ -1,2018 +0,0 @@
-/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.math.BigInteger;
-import java.security.*;
-import java.security.interfaces.*;
-import java.security.spec.*;
-import java.security.cert.*;
-import java.security.cert.Certificate;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-
-import java.lang.reflect.*;
-
-import javax.security.auth.x500.X500Principal;
-
-import javax.crypto.KeyGenerator;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.DHPublicKeySpec;
-
-import javax.net.ssl.*;
-
-import sun.security.internal.spec.TlsPrfParameterSpec;
-import sun.security.ssl.CipherSuite.*;
-import static sun.security.ssl.CipherSuite.PRF.*;
-import sun.security.util.KeyUtil;
-
-/**
- * Many data structures are involved in the handshake messages.  These
- * classes are used as structures, with public data members.  They are
- * not visible outside the SSL package.
- *
- * Handshake messages all have a common header format, and they are all
- * encoded in a "handshake data" SSL record substream.  The base class
- * here (HandshakeMessage) provides a common framework and records the
- * SSL record type of the particular handshake message.
- *
- * This file contains subclasses for all the basic handshake messages.
- * All handshake messages know how to encode and decode themselves on
- * SSL streams; this facilitates using the same code on SSL client and
- * server sides, although they don't send and receive the same messages.
- *
- * Messages also know how to print themselves, which is quite handy
- * for debugging.  They always identify their type, and can optionally
- * dump all of their content.
- *
- * @author David Brownell
- */
-public abstract class HandshakeMessage {
-
-    HandshakeMessage() { }
-
-    // enum HandshakeType:
-    static final byte   ht_hello_request = 0;
-    static final byte   ht_client_hello = 1;
-    static final byte   ht_server_hello = 2;
-
-    static final byte   ht_certificate = 11;
-    static final byte   ht_server_key_exchange = 12;
-    static final byte   ht_certificate_request = 13;
-    static final byte   ht_server_hello_done = 14;
-    static final byte   ht_certificate_verify = 15;
-    static final byte   ht_client_key_exchange = 16;
-
-    static final byte   ht_finished = 20;
-
-    /* Class and subclass dynamic debugging support */
-    public static final Debug debug = Debug.getInstance("ssl");
-
-    /**
-     * Utility method to convert a BigInteger to a byte array in unsigned
-     * format as needed in the handshake messages. BigInteger uses
-     * 2's complement format, i.e. it prepends an extra zero if the MSB
-     * is set. We remove that.
-     */
-    static byte[] toByteArray(BigInteger bi) {
-        byte[] b = bi.toByteArray();
-        if ((b.length > 1) && (b[0] == 0)) {
-            int n = b.length - 1;
-            byte[] newarray = new byte[n];
-            System.arraycopy(b, 1, newarray, 0, n);
-            b = newarray;
-        }
-        return b;
-    }
-
-    /*
-     * SSL 3.0 MAC padding constants.
-     * Also used by CertificateVerify and Finished during the handshake.
-     */
-    static final byte[] MD5_pad1 = genPad(0x36, 48);
-    static final byte[] MD5_pad2 = genPad(0x5c, 48);
-
-    static final byte[] SHA_pad1 = genPad(0x36, 40);
-    static final byte[] SHA_pad2 = genPad(0x5c, 40);
-
-    private static byte[] genPad(int b, int count) {
-        byte[] padding = new byte[count];
-        Arrays.fill(padding, (byte)b);
-        return padding;
-    }
-
-    /*
-     * Write a handshake message on the (handshake) output stream.
-     * This is just a four byte header followed by the data.
-     *
-     * NOTE that huge messages -- notably, ones with huge cert
-     * chains -- are handled correctly.
-     */
-    final void write(HandshakeOutStream s) throws IOException {
-        int len = messageLength();
-        if (len >= Record.OVERFLOW_OF_INT24) {
-            throw new SSLException("Handshake message too big"
-                + ", type = " + messageType() + ", len = " + len);
-        }
-        s.write(messageType());
-        s.putInt24(len);
-        send(s);
-    }
-
-    /*
-     * Subclasses implement these methods so those kinds of
-     * messages can be emitted.  Base class delegates to subclass.
-     */
-    abstract int  messageType();
-    abstract int  messageLength();
-    abstract void send(HandshakeOutStream s) throws IOException;
-
-    /*
-     * Write a descriptive message on the output stream; for debugging.
-     */
-    abstract void print(PrintStream p) throws IOException;
-
-//
-// NOTE:  the rest of these classes are nested within this one, and are
-// imported by other classes in this package.  There are a few other
-// handshake message classes, not neatly nested here because of current
-// licensing requirement for native (RSA) methods.  They belong here,
-// but those native methods complicate things a lot!
-//
-
-
-/*
- * HelloRequest ... SERVER --> CLIENT
- *
- * Server can ask the client to initiate a new handshake, e.g. to change
- * session parameters after a connection has been (re)established.
- */
-static final class HelloRequest extends HandshakeMessage {
-    int messageType() { return ht_hello_request; }
-
-    HelloRequest() { }
-
-    HelloRequest(HandshakeInStream in) throws IOException
-    {
-        // nothing in this message
-    }
-
-    int messageLength() { return 0; }
-
-    void send(HandshakeOutStream out) throws IOException
-    {
-        // nothing in this messaage
-    }
-
-    void print(PrintStream out) throws IOException
-    {
-        out.println("*** HelloRequest (empty)");
-    }
-
-}
-
-
-/*
- * ClientHello ... CLIENT --> SERVER
- *
- * Client initiates handshake by telling server what it wants, and what it
- * can support (prioritized by what's first in the ciphe suite list).
- *
- * By RFC2246:7.4.1.2 it's explicitly anticipated that this message
- * will have more data added at the end ... e.g. what CAs the client trusts.
- * Until we know how to parse it, we will just read what we know
- * about, and let our caller handle the jumps over unknown data.
- */
-static final class ClientHello extends HandshakeMessage {
-
-    ProtocolVersion     protocolVersion;
-    RandomCookie        clnt_random;
-    SessionId           sessionId;
-    private CipherSuiteList    cipherSuites;
-    byte[]              compression_methods;
-
-    HelloExtensions extensions = new HelloExtensions();
-
-    private final static byte[]  NULL_COMPRESSION = new byte[] {0};
-
-    ClientHello(SecureRandom generator, ProtocolVersion protocolVersion,
-            SessionId sessionId, CipherSuiteList cipherSuites) {
-
-        this.protocolVersion = protocolVersion;
-        this.sessionId = sessionId;
-        this.cipherSuites = cipherSuites;
-
-        if (cipherSuites.containsEC()) {
-            extensions.add(SupportedEllipticCurvesExtension.DEFAULT);
-            extensions.add(SupportedEllipticPointFormatsExtension.DEFAULT);
-        }
-
-        clnt_random = new RandomCookie(generator);
-        compression_methods = NULL_COMPRESSION;
-    }
-
-    ClientHello(HandshakeInStream s, int messageLength) throws IOException {
-        protocolVersion = ProtocolVersion.valueOf(s.getInt8(), s.getInt8());
-        clnt_random = new RandomCookie(s);
-        sessionId = new SessionId(s.getBytes8());
-        cipherSuites = new CipherSuiteList(s);
-        compression_methods = s.getBytes8();
-        if (messageLength() != messageLength) {
-            extensions = new HelloExtensions(s);
-        }
-    }
-
-    CipherSuiteList getCipherSuites() {
-        return cipherSuites;
-    }
-
-    // add renegotiation_info extension
-    void addRenegotiationInfoExtension(byte[] clientVerifyData) {
-        HelloExtension renegotiationInfo = new RenegotiationInfoExtension(
-                    clientVerifyData, new byte[0]);
-        extensions.add(renegotiationInfo);
-    }
-
-    // add server_name extension
-    void addServerNameIndicationExtension(String hostname) {
-        // We would have checked that the hostname ia a FQDN.
-        ArrayList<String> hostnames = new ArrayList<>(1);
-        hostnames.add(hostname);
-
-        try {
-            extensions.add(new ServerNameExtension(hostnames));
-        } catch (IOException ioe) {
-            // ignore the exception and return
-        }
-    }
-
-    // add signature_algorithm extension
-    void addSignatureAlgorithmsExtension(
-            Collection<SignatureAndHashAlgorithm> algorithms) {
-        HelloExtension signatureAlgorithm =
-                new SignatureAlgorithmsExtension(algorithms);
-        extensions.add(signatureAlgorithm);
-    }
-
-    @Override
-    int messageType() { return ht_client_hello; }
-
-    @Override
-    int messageLength() {
-        /*
-         * Add fixed size parts of each field...
-         * version + random + session + cipher + compress
-         */
-        return (2 + 32 + 1 + 2 + 1
-            + sessionId.length()                /* ... + variable parts */
-            + (cipherSuites.size() * 2)
-            + compression_methods.length)
-            + extensions.length();
-    }
-
-    @Override
-    void send(HandshakeOutStream s) throws IOException {
-        s.putInt8(protocolVersion.major);
-        s.putInt8(protocolVersion.minor);
-        clnt_random.send(s);
-        s.putBytes8(sessionId.getId());
-        cipherSuites.send(s);
-        s.putBytes8(compression_methods);
-        extensions.send(s);
-    }
-
-    @Override
-    void print(PrintStream s) throws IOException {
-        s.println("*** ClientHello, " + protocolVersion);
-
-        if (debug != null && Debug.isOn("verbose")) {
-            s.print("RandomCookie:  ");
-            clnt_random.print(s);
-
-            s.print("Session ID:  ");
-            s.println(sessionId);
-
-            s.println("Cipher Suites: " + cipherSuites);
-
-            Debug.println(s, "Compression Methods", compression_methods);
-            extensions.print(s);
-            s.println("***");
-        }
-    }
-}
-
-/*
- * ServerHello ... SERVER --> CLIENT
- *
- * Server chooses protocol options from among those it supports and the
- * client supports.  Then it sends the basic session descriptive parameters
- * back to the client.
- */
-static final
-class ServerHello extends HandshakeMessage
-{
-    int messageType() { return ht_server_hello; }
-
-    ProtocolVersion     protocolVersion;
-    RandomCookie        svr_random;
-    SessionId           sessionId;
-    CipherSuite         cipherSuite;
-    byte                compression_method;
-    HelloExtensions extensions = new HelloExtensions();
-
-    ServerHello() {
-        // empty
-    }
-
-    ServerHello(HandshakeInStream input, int messageLength)
-            throws IOException {
-        protocolVersion = ProtocolVersion.valueOf(input.getInt8(),
-                                                  input.getInt8());
-        svr_random = new RandomCookie(input);
-        sessionId = new SessionId(input.getBytes8());
-        cipherSuite = CipherSuite.valueOf(input.getInt8(), input.getInt8());
-        compression_method = (byte)input.getInt8();
-        if (messageLength() != messageLength) {
-            extensions = new HelloExtensions(input);
-        }
-    }
-
-    int messageLength()
-    {
-        // almost fixed size, except session ID and extensions:
-        //      major + minor = 2
-        //      random = 32
-        //      session ID len field = 1
-        //      cipher suite + compression = 3
-        //      extensions: if present, 2 + length of extensions
-        return 38 + sessionId.length() + extensions.length();
-    }
-
-    void send(HandshakeOutStream s) throws IOException
-    {
-        s.putInt8(protocolVersion.major);
-        s.putInt8(protocolVersion.minor);
-        svr_random.send(s);
-        s.putBytes8(sessionId.getId());
-        s.putInt8(cipherSuite.id >> 8);
-        s.putInt8(cipherSuite.id & 0xff);
-        s.putInt8(compression_method);
-        extensions.send(s);
-    }
-
-    void print(PrintStream s) throws IOException
-    {
-        s.println("*** ServerHello, " + protocolVersion);
-
-        if (debug != null && Debug.isOn("verbose")) {
-            s.print("RandomCookie:  ");
-            svr_random.print(s);
-
-            int i;
-
-            s.print("Session ID:  ");
-            s.println(sessionId);
-
-            s.println("Cipher Suite: " + cipherSuite);
-            s.println("Compression Method: " + compression_method);
-            extensions.print(s);
-            s.println("***");
-        }
-    }
-}
-
-
-/*
- * CertificateMsg ... send by both CLIENT and SERVER
- *
- * Each end of a connection may need to pass its certificate chain to
- * the other end.  Such chains are intended to validate an identity with
- * reference to some certifying authority.  Examples include companies
- * like Verisign, or financial institutions.  There's some control over
- * the certifying authorities which are sent.
- *
- * NOTE: that these messages might be huge, taking many handshake records.
- * Up to 2^48 bytes of certificate may be sent, in records of at most 2^14
- * bytes each ... up to 2^32 records sent on the output stream.
- */
-static final
-class CertificateMsg extends HandshakeMessage
-{
-    int messageType() { return ht_certificate; }
-
-    private X509Certificate[] chain;
-
-    private List<byte[]> encodedChain;
-
-    private int messageLength;
-
-    CertificateMsg(X509Certificate[] certs) {
-        chain = certs;
-    }
-
-    CertificateMsg(HandshakeInStream input) throws IOException {
-        int chainLen = input.getInt24();
-        List<Certificate> v = new ArrayList<>(4);
-
-        CertificateFactory cf = null;
-        while (chainLen > 0) {
-            byte[] cert = input.getBytes24();
-            chainLen -= (3 + cert.length);
-            try {
-                if (cf == null) {
-                    cf = CertificateFactory.getInstance("X.509");
-                }
-                v.add(cf.generateCertificate(new ByteArrayInputStream(cert)));
-            } catch (CertificateException e) {
-                throw (SSLProtocolException)new SSLProtocolException(
-                    e.getMessage()).initCause(e);
-            }
-        }
-
-        chain = v.toArray(new X509Certificate[v.size()]);
-    }
-
-    int messageLength() {
-        if (encodedChain == null) {
-            messageLength = 3;
-            encodedChain = new ArrayList<byte[]>(chain.length);
-            try {
-                for (X509Certificate cert : chain) {
-                    byte[] b = cert.getEncoded();
-                    encodedChain.add(b);
-                    messageLength += b.length + 3;
-                }
-            } catch (CertificateEncodingException e) {
-                encodedChain = null;
-                throw new RuntimeException("Could not encode certificates", e);
-            }
-        }
-        return messageLength;
-    }
-
-    void send(HandshakeOutStream s) throws IOException {
-        s.putInt24(messageLength() - 3);
-        for (byte[] b : encodedChain) {
-            s.putBytes24(b);
-        }
-    }
-
-    void print(PrintStream s) throws IOException {
-        s.println("*** Certificate chain");
-
-        if (debug != null && Debug.isOn("verbose")) {
-            for (int i = 0; i < chain.length; i++)
-                s.println("chain [" + i + "] = " + chain[i]);
-            s.println("***");
-        }
-    }
-
-    X509Certificate[] getCertificateChain() {
-        return chain.clone();
-    }
-}
-
-/*
- * ServerKeyExchange ... SERVER --> CLIENT
- *
- * The cipher suite selected, when combined with the certificate exchanged,
- * implies one of several different kinds of key exchange.  Most current
- * cipher suites require the server to send more than its certificate.
- *
- * The primary exceptions are when a server sends an encryption-capable
- * RSA public key in its cert, to be used with RSA (or RSA_export) key
- * exchange; and when a server sends its Diffie-Hellman cert.  Those kinds
- * of key exchange do not require a ServerKeyExchange message.
- *
- * Key exchange can be viewed as having three modes, which are explicit
- * for the Diffie-Hellman flavors and poorly specified for RSA ones:
- *
- *      - "Ephemeral" keys.  Here, a "temporary" key is allocated by the
- *        server, and signed.  Diffie-Hellman keys signed using RSA or
- *        DSS are ephemeral (DHE flavor).  RSA keys get used to do the same
- *        thing, to cut the key size down to 512 bits (export restrictions)
- *        or for signing-only RSA certificates.
- *
- *      - Anonymity.  Here no server certificate is sent, only the public
- *        key of the server.  This case is subject to man-in-the-middle
- *        attacks.  This can be done with Diffie-Hellman keys (DH_anon) or
- *        with RSA keys, but is only used in SSLv3 for DH_anon.
- *
- *      - "Normal" case.  Here a server certificate is sent, and the public
- *        key there is used directly in exchanging the premaster secret.
- *        For example, Diffie-Hellman "DH" flavor, and any RSA flavor with
- *        only 512 bit keys.
- *
- * If a server certificate is sent, there is no anonymity.  However,
- * when a certificate is sent, ephemeral keys may still be used to
- * exchange the premaster secret.  That's how RSA_EXPORT often works,
- * as well as how the DHE_* flavors work.
- */
-static abstract class ServerKeyExchange extends HandshakeMessage
-{
-    int messageType() { return ht_server_key_exchange; }
-}
-
-
-/*
- * Using RSA for Key Exchange:  exchange a session key that's not as big
- * as the signing-only key.  Used for export applications, since exported
- * RSA encryption keys can't be bigger than 512 bytes.
- *
- * This is never used when keys are 512 bits or smaller, and isn't used
- * on "US Domestic" ciphers in any case.
- */
-static final
-class RSA_ServerKeyExchange extends ServerKeyExchange
-{
-    private byte rsa_modulus[];     // 1 to 2^16 - 1 bytes
-    private byte rsa_exponent[];    // 1 to 2^16 - 1 bytes
-
-    private Signature signature;
-    private byte[] signatureBytes;
-
-    /*
-     * Hash the nonces and the ephemeral RSA public key.
-     */
-    private void updateSignature(byte clntNonce[], byte svrNonce[])
-            throws SignatureException {
-        int tmp;
-
-        signature.update(clntNonce);
-        signature.update(svrNonce);
-
-        tmp = rsa_modulus.length;
-        signature.update((byte)(tmp >> 8));
-        signature.update((byte)(tmp & 0x0ff));
-        signature.update(rsa_modulus);
-
-        tmp = rsa_exponent.length;
-        signature.update((byte)(tmp >> 8));
-        signature.update((byte)(tmp & 0x0ff));
-        signature.update(rsa_exponent);
-    }
-
-
-    /*
-     * Construct an RSA server key exchange message, using data
-     * known _only_ to the server.
-     *
-     * The client knows the public key corresponding to this private
-     * key, from the Certificate message sent previously.  To comply
-     * with US export regulations we use short RSA keys ... either
-     * long term ones in the server's X509 cert, or else ephemeral
-     * ones sent using this message.
-     */
-    RSA_ServerKeyExchange(PublicKey ephemeralKey, PrivateKey privateKey,
-            RandomCookie clntNonce, RandomCookie svrNonce, SecureRandom sr)
-            throws GeneralSecurityException {
-        RSAPublicKeySpec rsaKey = JsseJce.getRSAPublicKeySpec(ephemeralKey);
-        rsa_modulus = toByteArray(rsaKey.getModulus());
-        rsa_exponent = toByteArray(rsaKey.getPublicExponent());
-        signature = RSASignature.getInstance();
-        signature.initSign(privateKey, sr);
-        updateSignature(clntNonce.random_bytes, svrNonce.random_bytes);
-        signatureBytes = signature.sign();
-    }
-
-
-    /*
-     * Parse an RSA server key exchange message, using data known
-     * to the client (and, in some situations, eavesdroppers).
-     */
-    RSA_ServerKeyExchange(HandshakeInStream input)
-            throws IOException, NoSuchAlgorithmException {
-        signature = RSASignature.getInstance();
-        rsa_modulus = input.getBytes16();
-        rsa_exponent = input.getBytes16();
-        signatureBytes = input.getBytes16();
-    }
-
-    /*
-     * Get the ephemeral RSA public key that will be used in this
-     * SSL connection.
-     */
-    PublicKey getPublicKey() {
-        try {
-            KeyFactory kfac = JsseJce.getKeyFactory("RSA");
-            // modulus and exponent are always positive
-            RSAPublicKeySpec kspec = new RSAPublicKeySpec(
-                new BigInteger(1, rsa_modulus),
-                new BigInteger(1, rsa_exponent));
-            return kfac.generatePublic(kspec);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /*
-     * Verify the signed temporary key using the hashes computed
-     * from it and the two nonces.  This is called by clients
-     * with "exportable" RSA flavors.
-     */
-    boolean verify(PublicKey certifiedKey, RandomCookie clntNonce,
-            RandomCookie svrNonce) throws GeneralSecurityException {
-        signature.initVerify(certifiedKey);
-        updateSignature(clntNonce.random_bytes, svrNonce.random_bytes);
-        return signature.verify(signatureBytes);
-    }
-
-    int messageLength() {
-        return 6 + rsa_modulus.length + rsa_exponent.length
-               + signatureBytes.length;
-    }
-
-    void send(HandshakeOutStream s) throws IOException {
-        s.putBytes16(rsa_modulus);
-        s.putBytes16(rsa_exponent);
-        s.putBytes16(signatureBytes);
-    }
-
-    void print(PrintStream s) throws IOException {
-        s.println("*** RSA ServerKeyExchange");
-
-        if (debug != null && Debug.isOn("verbose")) {
-            Debug.println(s, "RSA Modulus", rsa_modulus);
-            Debug.println(s, "RSA Public Exponent", rsa_exponent);
-        }
-    }
-}
-
-
-/*
- * Using Diffie-Hellman algorithm for key exchange.  All we really need to
- * do is securely get Diffie-Hellman keys (using the same P, G parameters)
- * to our peer, then we automatically have a shared secret without need
- * to exchange any more data.  (D-H only solutions, such as SKIP, could
- * eliminate key exchange negotiations and get faster connection setup.
- * But they still need a signature algorithm like DSS/DSA to support the
- * trusted distribution of keys without relying on unscalable physical
- * key distribution systems.)
- *
- * This class supports several DH-based key exchange algorithms, though
- * perhaps eventually each deserves its own class.  Notably, this has
- * basic support for DH_anon and its DHE_DSS and DHE_RSA signed variants.
- */
-static final
-class DH_ServerKeyExchange extends ServerKeyExchange
-{
-    // Fix message encoding, see 4348279
-    private final static boolean dhKeyExchangeFix =
-        Debug.getBooleanProperty("com.sun.net.ssl.dhKeyExchangeFix", true);
-
-    private byte                dh_p [];        // 1 to 2^16 - 1 bytes
-    private byte                dh_g [];        // 1 to 2^16 - 1 bytes
-    private byte                dh_Ys [];       // 1 to 2^16 - 1 bytes
-
-    private byte                signature [];
-
-    // protocol version being established using this ServerKeyExchange message
-    ProtocolVersion protocolVersion;
-
-    // the preferable signature algorithm used by this ServerKeyExchange message
-    private SignatureAndHashAlgorithm preferableSignatureAlgorithm;
-
-    /*
-     * Construct from initialized DH key object, for DH_anon
-     * key exchange.
-     */
-    DH_ServerKeyExchange(DHCrypt obj, ProtocolVersion protocolVersion) {
-        this.protocolVersion = protocolVersion;
-        this.preferableSignatureAlgorithm = null;
-
-        // The DH key has been validated in the constructor of DHCrypt.
-        setValues(obj);
-        signature = null;
-    }
-
-    /*
-     * Construct from initialized DH key object and the key associated
-     * with the cert chain which was sent ... for DHE_DSS and DHE_RSA
-     * key exchange.  (Constructor called by server.)
-     */
-    DH_ServerKeyExchange(DHCrypt obj, PrivateKey key, byte clntNonce[],
-            byte svrNonce[], SecureRandom sr,
-            SignatureAndHashAlgorithm signAlgorithm,
-            ProtocolVersion protocolVersion) throws GeneralSecurityException {
-
-        this.protocolVersion = protocolVersion;
-
-        // The DH key has been validated in the constructor of DHCrypt.
-        setValues(obj);
-
-        Signature sig;
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            this.preferableSignatureAlgorithm = signAlgorithm;
-            sig = JsseJce.getSignature(signAlgorithm.getAlgorithmName());
-        } else {
-            this.preferableSignatureAlgorithm = null;
-            if (key.getAlgorithm().equals("DSA")) {
-                sig = JsseJce.getSignature(JsseJce.SIGNATURE_DSA);
-            } else {
-                sig = RSASignature.getInstance();
-            }
-        }
-
-        sig.initSign(key, sr);
-        updateSignature(sig, clntNonce, svrNonce);
-        signature = sig.sign();
-    }
-
-    /*
-     * Construct a DH_ServerKeyExchange message from an input
-     * stream, as if sent from server to client for use with
-     * DH_anon key exchange
-     */
-    DH_ServerKeyExchange(HandshakeInStream input,
-            ProtocolVersion protocolVersion)
-            throws IOException, GeneralSecurityException {
-
-        this.protocolVersion = protocolVersion;
-        this.preferableSignatureAlgorithm = null;
-
-        dh_p = input.getBytes16();
-        dh_g = input.getBytes16();
-        dh_Ys = input.getBytes16();
-        KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys),
-                                             new BigInteger(1, dh_p),
-                                             new BigInteger(1, dh_g)));
-
-        signature = null;
-    }
-
-    /*
-     * Construct a DH_ServerKeyExchange message from an input stream
-     * and a certificate, as if sent from server to client for use with
-     * DHE_DSS or DHE_RSA key exchange.  (Called by client.)
-     */
-    DH_ServerKeyExchange(HandshakeInStream input, PublicKey publicKey,
-            byte clntNonce[], byte svrNonce[], int messageSize,
-            Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs,
-            ProtocolVersion protocolVersion)
-            throws IOException, GeneralSecurityException {
-
-        this.protocolVersion = protocolVersion;
-
-        // read params: ServerDHParams
-        dh_p = input.getBytes16();
-        dh_g = input.getBytes16();
-        dh_Ys = input.getBytes16();
-        KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys),
-                                             new BigInteger(1, dh_p),
-                                             new BigInteger(1, dh_g)));
-
-        // read the signature and hash algorithm
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            int hash = input.getInt8();         // hash algorithm
-            int signature = input.getInt8();    // signature algorithm
-
-            preferableSignatureAlgorithm =
-                SignatureAndHashAlgorithm.valueOf(hash, signature, 0);
-
-            // Is it a local supported signature algorithm?
-            if (!localSupportedSignAlgs.contains(
-                    preferableSignatureAlgorithm)) {
-                throw new SSLHandshakeException(
-                        "Unsupported SignatureAndHashAlgorithm in " +
-                        "ServerKeyExchange message");
-            }
-        } else {
-            this.preferableSignatureAlgorithm = null;
-        }
-
-        // read the signature
-        byte signature[];
-        if (dhKeyExchangeFix) {
-            signature = input.getBytes16();
-        } else {
-            messageSize -= (dh_p.length + 2);
-            messageSize -= (dh_g.length + 2);
-            messageSize -= (dh_Ys.length + 2);
-
-            signature = new byte[messageSize];
-            input.read(signature);
-        }
-
-        Signature sig;
-        String algorithm = publicKey.getAlgorithm();
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            sig = JsseJce.getSignature(
-                        preferableSignatureAlgorithm.getAlgorithmName());
-        } else {
-            if (algorithm.equals("DSA")) {
-                sig = JsseJce.getSignature(JsseJce.SIGNATURE_DSA);
-            } else if (algorithm.equals("RSA")) {
-                sig = RSASignature.getInstance();
-            } else {
-                throw new SSLKeyException("neither an RSA or a DSA key");
-            }
-        }
-
-        sig.initVerify(publicKey);
-        updateSignature(sig, clntNonce, svrNonce);
-
-        if (sig.verify(signature) == false ) {
-            throw new SSLKeyException("Server D-H key verification failed");
-        }
-    }
-
-    /* Return the Diffie-Hellman modulus */
-    BigInteger getModulus() {
-        return new BigInteger(1, dh_p);
-    }
-
-    /* Return the Diffie-Hellman base/generator */
-    BigInteger getBase() {
-        return new BigInteger(1, dh_g);
-    }
-
-    /* Return the server's Diffie-Hellman public key */
-    BigInteger getServerPublicKey() {
-        return new BigInteger(1, dh_Ys);
-    }
-
-    /*
-     * Update sig with nonces and Diffie-Hellman public key.
-     */
-    private void updateSignature(Signature sig, byte clntNonce[],
-            byte svrNonce[]) throws SignatureException {
-        int tmp;
-
-        sig.update(clntNonce);
-        sig.update(svrNonce);
-
-        tmp = dh_p.length;
-        sig.update((byte)(tmp >> 8));
-        sig.update((byte)(tmp & 0x0ff));
-        sig.update(dh_p);
-
-        tmp = dh_g.length;
-        sig.update((byte)(tmp >> 8));
-        sig.update((byte)(tmp & 0x0ff));
-        sig.update(dh_g);
-
-        tmp = dh_Ys.length;
-        sig.update((byte)(tmp >> 8));
-        sig.update((byte)(tmp & 0x0ff));
-        sig.update(dh_Ys);
-    }
-
-    private void setValues(DHCrypt obj) {
-        dh_p = toByteArray(obj.getModulus());
-        dh_g = toByteArray(obj.getBase());
-        dh_Ys = toByteArray(obj.getPublicKey());
-    }
-
-    int messageLength() {
-        int temp = 6;   // overhead for p, g, y(s) values.
-
-        temp += dh_p.length;
-        temp += dh_g.length;
-        temp += dh_Ys.length;
-
-        if (signature != null) {
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                temp += SignatureAndHashAlgorithm.sizeInRecord();
-            }
-
-            temp += signature.length;
-            if (dhKeyExchangeFix) {
-                temp += 2;
-            }
-        }
-
-        return temp;
-    }
-
-    void send(HandshakeOutStream s) throws IOException {
-        s.putBytes16(dh_p);
-        s.putBytes16(dh_g);
-        s.putBytes16(dh_Ys);
-
-        if (signature != null) {
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                s.putInt8(preferableSignatureAlgorithm.getHashValue());
-                s.putInt8(preferableSignatureAlgorithm.getSignatureValue());
-            }
-
-            if (dhKeyExchangeFix) {
-                s.putBytes16(signature);
-            } else {
-                s.write(signature);
-            }
-        }
-    }
-
-    void print(PrintStream s) throws IOException {
-        s.println("*** Diffie-Hellman ServerKeyExchange");
-
-        if (debug != null && Debug.isOn("verbose")) {
-            Debug.println(s, "DH Modulus", dh_p);
-            Debug.println(s, "DH Base", dh_g);
-            Debug.println(s, "Server DH Public Key", dh_Ys);
-
-            if (signature == null) {
-                s.println("Anonymous");
-            } else {
-                if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                    s.println("Signature Algorithm " +
-                        preferableSignatureAlgorithm.getAlgorithmName());
-                }
-
-                s.println("Signed with a DSA or RSA public key");
-            }
-        }
-    }
-}
-
-/*
- * ECDH server key exchange message. Sent by the server for ECDHE and ECDH_anon
- * ciphersuites to communicate its ephemeral public key (including the
- * EC domain parameters).
- *
- * We support named curves only, no explicitly encoded curves.
- */
-static final
-class ECDH_ServerKeyExchange extends ServerKeyExchange {
-
-    // constants for ECCurveType
-    private final static int CURVE_EXPLICIT_PRIME = 1;
-    private final static int CURVE_EXPLICIT_CHAR2 = 2;
-    private final static int CURVE_NAMED_CURVE    = 3;
-
-    // id of the curve we are using
-    private int curveId;
-    // encoded public point
-    private byte[] pointBytes;
-
-    // signature bytes (or null if anonymous)
-    private byte[] signatureBytes;
-
-    // public key object encapsulated in this message
-    private ECPublicKey publicKey;
-
-    // protocol version being established using this ServerKeyExchange message
-    ProtocolVersion protocolVersion;
-
-    // the preferable signature algorithm used by this ServerKeyExchange message
-    private SignatureAndHashAlgorithm preferableSignatureAlgorithm;
-
-    ECDH_ServerKeyExchange(ECDHCrypt obj, PrivateKey privateKey,
-            byte[] clntNonce, byte[] svrNonce, SecureRandom sr,
-            SignatureAndHashAlgorithm signAlgorithm,
-            ProtocolVersion protocolVersion) throws GeneralSecurityException {
-
-        this.protocolVersion = protocolVersion;
-
-        publicKey = (ECPublicKey)obj.getPublicKey();
-        ECParameterSpec params = publicKey.getParams();
-        ECPoint point = publicKey.getW();
-        pointBytes = JsseJce.encodePoint(point, params.getCurve());
-        curveId = SupportedEllipticCurvesExtension.getCurveIndex(params);
-
-        if (privateKey == null) {
-            // ECDH_anon
-            return;
-        }
-
-        Signature sig;
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            this.preferableSignatureAlgorithm = signAlgorithm;
-            sig = JsseJce.getSignature(signAlgorithm.getAlgorithmName());
-        } else {
-            sig = getSignature(privateKey.getAlgorithm());
-        }
-        sig.initSign(privateKey);  // where is the SecureRandom?
-
-        updateSignature(sig, clntNonce, svrNonce);
-        signatureBytes = sig.sign();
-    }
-
-    /*
-     * Parse an ECDH server key exchange message.
-     */
-    ECDH_ServerKeyExchange(HandshakeInStream input, PublicKey signingKey,
-            byte[] clntNonce, byte[] svrNonce,
-            Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs,
-            ProtocolVersion protocolVersion)
-            throws IOException, GeneralSecurityException {
-
-        this.protocolVersion = protocolVersion;
-
-        // read params: ServerECDHParams
-        int curveType = input.getInt8();
-        ECParameterSpec parameters;
-        // These parsing errors should never occur as we negotiated
-        // the supported curves during the exchange of the Hello messages.
-        if (curveType == CURVE_NAMED_CURVE) {
-            curveId = input.getInt16();
-            if (SupportedEllipticCurvesExtension.isSupported(curveId)
-                    == false) {
-                throw new SSLHandshakeException(
-                    "Unsupported curveId: " + curveId);
-            }
-            String curveOid =
-                SupportedEllipticCurvesExtension.getCurveOid(curveId);
-            if (curveOid == null) {
-                throw new SSLHandshakeException(
-                    "Unknown named curve: " + curveId);
-            }
-            parameters = JsseJce.getECParameterSpec(curveOid);
-            if (parameters == null) {
-                throw new SSLHandshakeException(
-                    "Unsupported curve: " + curveOid);
-            }
-        } else {
-            throw new SSLHandshakeException(
-                "Unsupported ECCurveType: " + curveType);
-        }
-        pointBytes = input.getBytes8();
-
-        ECPoint point = JsseJce.decodePoint(pointBytes, parameters.getCurve());
-        KeyFactory factory = JsseJce.getKeyFactory("EC");
-        publicKey = (ECPublicKey)factory.generatePublic(
-            new ECPublicKeySpec(point, parameters));
-
-        if (signingKey == null) {
-            // ECDH_anon
-            return;
-        }
-
-        // read the signature and hash algorithm
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            int hash = input.getInt8();         // hash algorithm
-            int signature = input.getInt8();    // signature algorithm
-
-            preferableSignatureAlgorithm =
-                SignatureAndHashAlgorithm.valueOf(hash, signature, 0);
-
-            // Is it a local supported signature algorithm?
-            if (!localSupportedSignAlgs.contains(
-                    preferableSignatureAlgorithm)) {
-                throw new SSLHandshakeException(
-                        "Unsupported SignatureAndHashAlgorithm in " +
-                        "ServerKeyExchange message");
-            }
-        }
-
-        // read the signature
-        signatureBytes = input.getBytes16();
-
-        // verify the signature
-        Signature sig;
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            sig = JsseJce.getSignature(
-                        preferableSignatureAlgorithm.getAlgorithmName());
-        } else {
-            sig = getSignature(signingKey.getAlgorithm());
-        }
-        sig.initVerify(signingKey);
-
-        updateSignature(sig, clntNonce, svrNonce);
-
-        if (sig.verify(signatureBytes) == false ) {
-            throw new SSLKeyException(
-                "Invalid signature on ECDH server key exchange message");
-        }
-    }
-
-    /*
-     * Get the ephemeral EC public key encapsulated in this message.
-     */
-    ECPublicKey getPublicKey() {
-        return publicKey;
-    }
-
-    private static Signature getSignature(String keyAlgorithm)
-            throws NoSuchAlgorithmException {
-        if (keyAlgorithm.equals("EC")) {
-            return JsseJce.getSignature(JsseJce.SIGNATURE_ECDSA);
-        } else if (keyAlgorithm.equals("RSA")) {
-            return RSASignature.getInstance();
-        } else {
-            throw new NoSuchAlgorithmException("neither an RSA or a EC key");
-        }
-    }
-
-    private void updateSignature(Signature sig, byte clntNonce[],
-            byte svrNonce[]) throws SignatureException {
-        sig.update(clntNonce);
-        sig.update(svrNonce);
-
-        sig.update((byte)CURVE_NAMED_CURVE);
-        sig.update((byte)(curveId >> 8));
-        sig.update((byte)curveId);
-        sig.update((byte)pointBytes.length);
-        sig.update(pointBytes);
-    }
-
-    int messageLength() {
-        int sigLen = 0;
-        if (signatureBytes != null) {
-            sigLen = 2 + signatureBytes.length;
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                sigLen += SignatureAndHashAlgorithm.sizeInRecord();
-            }
-        }
-
-        return 4 + pointBytes.length + sigLen;
-    }
-
-    void send(HandshakeOutStream s) throws IOException {
-        s.putInt8(CURVE_NAMED_CURVE);
-        s.putInt16(curveId);
-        s.putBytes8(pointBytes);
-
-        if (signatureBytes != null) {
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                s.putInt8(preferableSignatureAlgorithm.getHashValue());
-                s.putInt8(preferableSignatureAlgorithm.getSignatureValue());
-            }
-
-            s.putBytes16(signatureBytes);
-        }
-    }
-
-    void print(PrintStream s) throws IOException {
-        s.println("*** ECDH ServerKeyExchange");
-
-        if (debug != null && Debug.isOn("verbose")) {
-            if (signatureBytes == null) {
-                s.println("Anonymous");
-            } else {
-                if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                    s.println("Signature Algorithm " +
-                            preferableSignatureAlgorithm.getAlgorithmName());
-                }
-            }
-
-            s.println("Server key: " + publicKey);
-        }
-    }
-}
-
-static final class DistinguishedName {
-
-    /*
-     * DER encoded distinguished name.
-     * TLS requires that its not longer than 65535 bytes.
-     */
-    byte name[];
-
-    DistinguishedName(HandshakeInStream input) throws IOException {
-        name = input.getBytes16();
-    }
-
-    DistinguishedName(X500Principal dn) {
-        name = dn.getEncoded();
-    }
-
-    X500Principal getX500Principal() throws IOException {
-        try {
-            return new X500Principal(name);
-        } catch (IllegalArgumentException e) {
-            throw (SSLProtocolException)new SSLProtocolException(
-                e.getMessage()).initCause(e);
-        }
-    }
-
-    int length() {
-        return 2 + name.length;
-    }
-
-    void send(HandshakeOutStream output) throws IOException {
-        output.putBytes16(name);
-    }
-
-    void print(PrintStream output) throws IOException {
-        X500Principal principal = new X500Principal(name);
-        output.println("<" + principal.toString() + ">");
-    }
-}
-
-/*
- * CertificateRequest ... SERVER --> CLIENT
- *
- * Authenticated servers may ask clients to authenticate themselves
- * in turn, using this message.
- *
- * Prior to TLS 1.2, the structure of the message is defined as:
- *     struct {
- *         ClientCertificateType certificate_types<1..2^8-1>;
- *         DistinguishedName certificate_authorities<0..2^16-1>;
- *     } CertificateRequest;
- *
- * In TLS 1.2, the structure is changed to:
- *     struct {
- *         ClientCertificateType certificate_types<1..2^8-1>;
- *         SignatureAndHashAlgorithm
- *           supported_signature_algorithms<2^16-1>;
- *         DistinguishedName certificate_authorities<0..2^16-1>;
- *     } CertificateRequest;
- *
- */
-static final
-class CertificateRequest extends HandshakeMessage
-{
-    // enum ClientCertificateType
-    static final int   cct_rsa_sign = 1;
-    static final int   cct_dss_sign = 2;
-    static final int   cct_rsa_fixed_dh = 3;
-    static final int   cct_dss_fixed_dh = 4;
-
-    // The existance of these two values is a bug in the SSL specification.
-    // They are never used in the protocol.
-    static final int   cct_rsa_ephemeral_dh = 5;
-    static final int   cct_dss_ephemeral_dh = 6;
-
-    // From RFC 4492 (ECC)
-    static final int    cct_ecdsa_sign       = 64;
-    static final int    cct_rsa_fixed_ecdh   = 65;
-    static final int    cct_ecdsa_fixed_ecdh = 66;
-
-    private final static byte[] TYPES_NO_ECC = { cct_rsa_sign, cct_dss_sign };
-    private final static byte[] TYPES_ECC =
-        { cct_rsa_sign, cct_dss_sign, cct_ecdsa_sign };
-
-    byte                types [];               // 1 to 255 types
-    DistinguishedName   authorities [];         // 3 to 2^16 - 1
-        // ... "3" because that's the smallest DER-encoded X500 DN
-
-    // protocol version being established using this CertificateRequest message
-    ProtocolVersion protocolVersion;
-
-    // supported_signature_algorithms for TLS 1.2 or later
-    private Collection<SignatureAndHashAlgorithm> algorithms;
-
-    // length of supported_signature_algorithms
-    private int algorithmsLen;
-
-    CertificateRequest(X509Certificate ca[], KeyExchange keyExchange,
-            Collection<SignatureAndHashAlgorithm> signAlgs,
-            ProtocolVersion protocolVersion) throws IOException {
-
-        this.protocolVersion = protocolVersion;
-
-        // always use X500Principal
-        authorities = new DistinguishedName[ca.length];
-        for (int i = 0; i < ca.length; i++) {
-            X500Principal x500Principal = ca[i].getSubjectX500Principal();
-            authorities[i] = new DistinguishedName(x500Principal);
-        }
-        // we support RSA, DSS, and ECDSA client authentication and they
-        // can be used with all ciphersuites. If this changes, the code
-        // needs to be adapted to take keyExchange into account.
-        // We only request ECDSA client auth if we have ECC crypto available.
-        this.types = JsseJce.isEcAvailable() ? TYPES_ECC : TYPES_NO_ECC;
-
-        // Use supported_signature_algorithms for TLS 1.2 or later.
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            if (signAlgs == null || signAlgs.isEmpty()) {
-                throw new SSLProtocolException(
-                        "No supported signature algorithms");
-            }
-
-            algorithms = new ArrayList<SignatureAndHashAlgorithm>(signAlgs);
-            algorithmsLen =
-                SignatureAndHashAlgorithm.sizeInRecord() * algorithms.size();
-        } else {
-            algorithms = new ArrayList<SignatureAndHashAlgorithm>();
-            algorithmsLen = 0;
-        }
-    }
-
-    CertificateRequest(HandshakeInStream input,
-            ProtocolVersion protocolVersion) throws IOException {
-
-        this.protocolVersion = protocolVersion;
-
-        // Read the certificate_types.
-        types = input.getBytes8();
-
-        // Read the supported_signature_algorithms for TLS 1.2 or later.
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            algorithmsLen = input.getInt16();
-            if (algorithmsLen < 2) {
-                throw new SSLProtocolException(
-                        "Invalid supported_signature_algorithms field");
-            }
-
-            algorithms = new ArrayList<SignatureAndHashAlgorithm>();
-            int remains = algorithmsLen;
-            int sequence = 0;
-            while (remains > 1) {    // needs at least two bytes
-                int hash = input.getInt8();         // hash algorithm
-                int signature = input.getInt8();    // signature algorithm
-
-                SignatureAndHashAlgorithm algorithm =
-                    SignatureAndHashAlgorithm.valueOf(hash, signature,
-                                                                ++sequence);
-                algorithms.add(algorithm);
-                remains -= 2;  // one byte for hash, one byte for signature
-            }
-
-            if (remains != 0) {
-                throw new SSLProtocolException(
-                        "Invalid supported_signature_algorithms field");
-            }
-        } else {
-            algorithms = new ArrayList<SignatureAndHashAlgorithm>();
-            algorithmsLen = 0;
-        }
-
-        // read the certificate_authorities
-        int len = input.getInt16();
-        ArrayList<DistinguishedName> v = new ArrayList<>();
-        while (len >= 3) {
-            DistinguishedName dn = new DistinguishedName(input);
-            v.add(dn);
-            len -= dn.length();
-        }
-
-        if (len != 0) {
-            throw new SSLProtocolException("Bad CertificateRequest DN length");
-        }
-
-        authorities = v.toArray(new DistinguishedName[v.size()]);
-    }
-
-    X500Principal[] getAuthorities() throws IOException {
-        X500Principal[] ret = new X500Principal[authorities.length];
-        for (int i = 0; i < authorities.length; i++) {
-            ret[i] = authorities[i].getX500Principal();
-        }
-        return ret;
-    }
-
-    Collection<SignatureAndHashAlgorithm> getSignAlgorithms() {
-        return algorithms;
-    }
-
-    @Override
-    int messageType() {
-        return ht_certificate_request;
-    }
-
-    @Override
-    int messageLength() {
-        int len = 1 + types.length + 2;
-
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            len += algorithmsLen + 2;
-        }
-
-        for (int i = 0; i < authorities.length; i++) {
-            len += authorities[i].length();
-        }
-
-        return len;
-    }
-
-    @Override
-    void send(HandshakeOutStream output) throws IOException {
-        // put certificate_types
-        output.putBytes8(types);
-
-        // put supported_signature_algorithms
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            output.putInt16(algorithmsLen);
-            for (SignatureAndHashAlgorithm algorithm : algorithms) {
-                output.putInt8(algorithm.getHashValue());      // hash
-                output.putInt8(algorithm.getSignatureValue()); // signature
-            }
-        }
-
-        // put certificate_authorities
-        int len = 0;
-        for (int i = 0; i < authorities.length; i++) {
-            len += authorities[i].length();
-        }
-
-        output.putInt16(len);
-        for (int i = 0; i < authorities.length; i++) {
-            authorities[i].send(output);
-        }
-    }
-
-    @Override
-    void print(PrintStream s) throws IOException {
-        s.println("*** CertificateRequest");
-
-        if (debug != null && Debug.isOn("verbose")) {
-            s.print("Cert Types: ");
-            for (int i = 0; i < types.length; i++) {
-                switch (types[i]) {
-                  case cct_rsa_sign:
-                    s.print("RSA"); break;
-                  case cct_dss_sign:
-                    s.print("DSS"); break;
-                  case cct_rsa_fixed_dh:
-                    s.print("Fixed DH (RSA sig)"); break;
-                  case cct_dss_fixed_dh:
-                    s.print("Fixed DH (DSS sig)"); break;
-                  case cct_rsa_ephemeral_dh:
-                    s.print("Ephemeral DH (RSA sig)"); break;
-                  case cct_dss_ephemeral_dh:
-                    s.print("Ephemeral DH (DSS sig)"); break;
-                  case cct_ecdsa_sign:
-                    s.print("ECDSA"); break;
-                  case cct_rsa_fixed_ecdh:
-                    s.print("Fixed ECDH (RSA sig)"); break;
-                  case cct_ecdsa_fixed_ecdh:
-                    s.print("Fixed ECDH (ECDSA sig)"); break;
-                  default:
-                    s.print("Type-" + (types[i] & 0xff)); break;
-                }
-                if (i != types.length - 1) {
-                    s.print(", ");
-                }
-            }
-            s.println();
-
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                StringBuffer buffer = new StringBuffer();
-                boolean opened = false;
-                for (SignatureAndHashAlgorithm signAlg : algorithms) {
-                    if (opened) {
-                        buffer.append(", " + signAlg.getAlgorithmName());
-                    } else {
-                        buffer.append(signAlg.getAlgorithmName());
-                        opened = true;
-                    }
-                }
-                s.println("Supported Signature Algorithms: " + buffer);
-            }
-
-            s.println("Cert Authorities:");
-            if (authorities.length == 0) {
-                s.println("<Empty>");
-            } else {
-                for (int i = 0; i < authorities.length; i++) {
-                    authorities[i].print(s);
-                }
-            }
-        }
-    }
-}
-
-
-/*
- * ServerHelloDone ... SERVER --> CLIENT
- *
- * When server's done sending its messages in response to the client's
- * "hello" (e.g. its own hello, certificate, key exchange message, perhaps
- * client certificate request) it sends this message to flag that it's
- * done that part of the handshake.
- */
-static final
-class ServerHelloDone extends HandshakeMessage
-{
-    int messageType() { return ht_server_hello_done; }
-
-    ServerHelloDone() { }
-
-    ServerHelloDone(HandshakeInStream input)
-    {
-        // nothing to do
-    }
-
-    int messageLength()
-    {
-        return 0;
-    }
-
-    void send(HandshakeOutStream s) throws IOException
-    {
-        // nothing to send
-    }
-
-    void print(PrintStream s) throws IOException
-    {
-        s.println("*** ServerHelloDone");
-    }
-}
-
-
-/*
- * CertificateVerify ... CLIENT --> SERVER
- *
- * Sent after client sends signature-capable certificates (e.g. not
- * Diffie-Hellman) to verify.
- */
-static final class CertificateVerify extends HandshakeMessage {
-
-    // the signature bytes
-    private byte[] signature;
-
-    // protocol version being established using this ServerKeyExchange message
-    ProtocolVersion protocolVersion;
-
-    // the preferable signature algorithm used by this CertificateVerify message
-    private SignatureAndHashAlgorithm preferableSignatureAlgorithm = null;
-
-    /*
-     * Create an RSA or DSA signed certificate verify message.
-     */
-    CertificateVerify(ProtocolVersion protocolVersion,
-            HandshakeHash handshakeHash, PrivateKey privateKey,
-            SecretKey masterSecret, SecureRandom sr,
-            SignatureAndHashAlgorithm signAlgorithm)
-            throws GeneralSecurityException {
-
-        this.protocolVersion = protocolVersion;
-
-        String algorithm = privateKey.getAlgorithm();
-        Signature sig = null;
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            this.preferableSignatureAlgorithm = signAlgorithm;
-            sig = JsseJce.getSignature(signAlgorithm.getAlgorithmName());
-        } else {
-            sig = getSignature(protocolVersion, algorithm);
-        }
-        sig.initSign(privateKey, sr);
-        updateSignature(sig, protocolVersion, handshakeHash, algorithm,
-                        masterSecret);
-        signature = sig.sign();
-    }
-
-    //
-    // Unmarshal the signed data from the input stream.
-    //
-    CertificateVerify(HandshakeInStream input,
-            Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs,
-            ProtocolVersion protocolVersion) throws IOException  {
-
-        this.protocolVersion = protocolVersion;
-
-        // read the signature and hash algorithm
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            int hashAlg = input.getInt8();         // hash algorithm
-            int signAlg = input.getInt8();         // signature algorithm
-
-            preferableSignatureAlgorithm =
-                SignatureAndHashAlgorithm.valueOf(hashAlg, signAlg, 0);
-
-            // Is it a local supported signature algorithm?
-            if (!localSupportedSignAlgs.contains(
-                    preferableSignatureAlgorithm)) {
-                throw new SSLHandshakeException(
-                        "Unsupported SignatureAndHashAlgorithm in " +
-                        "ServerKeyExchange message");
-            }
-        }
-
-        // read the signature
-        signature = input.getBytes16();
-    }
-
-    /*
-     * Get the preferable signature algorithm used by this message
-     */
-    SignatureAndHashAlgorithm getPreferableSignatureAlgorithm() {
-        return preferableSignatureAlgorithm;
-    }
-
-    /*
-     * Verify a certificate verify message. Return the result of verification,
-     * if there is a problem throw a GeneralSecurityException.
-     */
-    boolean verify(ProtocolVersion protocolVersion,
-            HandshakeHash handshakeHash, PublicKey publicKey,
-            SecretKey masterSecret) throws GeneralSecurityException {
-        String algorithm = publicKey.getAlgorithm();
-        Signature sig = null;
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            sig = JsseJce.getSignature(
-                        preferableSignatureAlgorithm.getAlgorithmName());
-        } else {
-            sig = getSignature(protocolVersion, algorithm);
-        }
-        sig.initVerify(publicKey);
-        updateSignature(sig, protocolVersion, handshakeHash, algorithm,
-                        masterSecret);
-        return sig.verify(signature);
-    }
-
-    /*
-     * Get the Signature object appropriate for verification using the
-     * given signature algorithm and protocol version.
-     */
-    private static Signature getSignature(ProtocolVersion protocolVersion,
-            String algorithm) throws GeneralSecurityException {
-        if (algorithm.equals("RSA")) {
-            return RSASignature.getInternalInstance();
-        } else if (algorithm.equals("DSA")) {
-            return JsseJce.getSignature(JsseJce.SIGNATURE_RAWDSA);
-        } else if (algorithm.equals("EC")) {
-            return JsseJce.getSignature(JsseJce.SIGNATURE_RAWECDSA);
-        } else {
-            throw new SignatureException("Unrecognized algorithm: "
-                + algorithm);
-        }
-    }
-
-    /*
-     * Update the Signature with the data appropriate for the given
-     * signature algorithm and protocol version so that the object is
-     * ready for signing or verifying.
-     */
-    private static void updateSignature(Signature sig,
-            ProtocolVersion protocolVersion,
-            HandshakeHash handshakeHash, String algorithm, SecretKey masterKey)
-            throws SignatureException {
-
-        if (algorithm.equals("RSA")) {
-            if (protocolVersion.v < ProtocolVersion.TLS12.v) { // TLS1.1-
-                MessageDigest md5Clone = handshakeHash.getMD5Clone();
-                MessageDigest shaClone = handshakeHash.getSHAClone();
-
-                if (protocolVersion.v < ProtocolVersion.TLS10.v) { // SSLv3
-                    updateDigest(md5Clone, MD5_pad1, MD5_pad2, masterKey);
-                    updateDigest(shaClone, SHA_pad1, SHA_pad2, masterKey);
-                }
-
-                // The signature must be an instance of RSASignature, need
-                // to use these hashes directly.
-                RSASignature.setHashes(sig, md5Clone, shaClone);
-            } else {  // TLS1.2+
-                sig.update(handshakeHash.getAllHandshakeMessages());
-            }
-        } else { // DSA, ECDSA
-            if (protocolVersion.v < ProtocolVersion.TLS12.v) { // TLS1.1-
-                MessageDigest shaClone = handshakeHash.getSHAClone();
-
-                if (protocolVersion.v < ProtocolVersion.TLS10.v) { // SSLv3
-                    updateDigest(shaClone, SHA_pad1, SHA_pad2, masterKey);
-                }
-
-                sig.update(shaClone.digest());
-            } else {  // TLS1.2+
-                sig.update(handshakeHash.getAllHandshakeMessages());
-            }
-        }
-    }
-
-    /*
-     * Update the MessageDigest for SSLv3 certificate verify or finished
-     * message calculation. The digest must already have been updated with
-     * all preceding handshake messages.
-     * Used by the Finished class as well.
-     */
-    private static void updateDigest(MessageDigest md,
-            byte[] pad1, byte[] pad2,
-            SecretKey masterSecret) {
-        // Digest the key bytes if available.
-        // Otherwise (sensitive key), try digesting the key directly.
-        // That is currently only implemented in SunPKCS11 using a private
-        // reflection API, so we avoid that if possible.
-        byte[] keyBytes = "RAW".equals(masterSecret.getFormat())
-                        ? masterSecret.getEncoded() : null;
-        if (keyBytes != null) {
-            md.update(keyBytes);
-        } else {
-            digestKey(md, masterSecret);
-        }
-        md.update(pad1);
-        byte[] temp = md.digest();
-
-        if (keyBytes != null) {
-            md.update(keyBytes);
-        } else {
-            digestKey(md, masterSecret);
-        }
-        md.update(pad2);
-        md.update(temp);
-    }
-
-    private final static Class delegate;
-    private final static Field spiField;
-
-    static {
-        try {
-            delegate = Class.forName("java.security.MessageDigest$Delegate");
-            spiField = delegate.getDeclaredField("digestSpi");
-        } catch (Exception e) {
-            throw new RuntimeException("Reflection failed", e);
-        }
-        makeAccessible(spiField);
-    }
-
-    private static void makeAccessible(final AccessibleObject o) {
-        AccessController.doPrivileged(new PrivilegedAction<Object>() {
-            public Object run() {
-                o.setAccessible(true);
-                return null;
-            }
-        });
-    }
-
-    // ConcurrentHashMap does not allow null values, use this marker object
-    private final static Object NULL_OBJECT = new Object();
-
-    // cache Method objects per Spi class
-    // Note that this will prevent the Spi classes from being GC'd. We assume
-    // that is not a problem.
-    private final static Map<Class,Object> methodCache =
-                                        new ConcurrentHashMap<>();
-
-    private static void digestKey(MessageDigest md, SecretKey key) {
-        try {
-            // Verify that md is implemented via MessageDigestSpi, not
-            // via JDK 1.1 style MessageDigest subclassing.
-            if (md.getClass() != delegate) {
-                throw new Exception("Digest is not a MessageDigestSpi");
-            }
-            MessageDigestSpi spi = (MessageDigestSpi)spiField.get(md);
-            Class<?> clazz = spi.getClass();
-            Object r = methodCache.get(clazz);
-            if (r == null) {
-                try {
-                    r = clazz.getDeclaredMethod("implUpdate", SecretKey.class);
-                    makeAccessible((Method)r);
-                } catch (NoSuchMethodException e) {
-                    r = NULL_OBJECT;
-                }
-                methodCache.put(clazz, r);
-            }
-            if (r == NULL_OBJECT) {
-                throw new Exception(
-                    "Digest does not support implUpdate(SecretKey)");
-            }
-            Method update = (Method)r;
-            update.invoke(spi, key);
-        } catch (Exception e) {
-            throw new RuntimeException(
-                "Could not obtain encoded key and "
-                + "MessageDigest cannot digest key", e);
-        }
-    }
-
-    @Override
-    int messageType() {
-        return ht_certificate_verify;
-    }
-
-    @Override
-    int messageLength() {
-        int temp = 2;
-
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            temp += SignatureAndHashAlgorithm.sizeInRecord();
-        }
-
-        return temp + signature.length;
-    }
-
-    @Override
-    void send(HandshakeOutStream s) throws IOException {
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            s.putInt8(preferableSignatureAlgorithm.getHashValue());
-            s.putInt8(preferableSignatureAlgorithm.getSignatureValue());
-        }
-
-        s.putBytes16(signature);
-    }
-
-    @Override
-    void print(PrintStream s) throws IOException {
-        s.println("*** CertificateVerify");
-
-        if (debug != null && Debug.isOn("verbose")) {
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                s.println("Signature Algorithm " +
-                        preferableSignatureAlgorithm.getAlgorithmName());
-            }
-        }
-    }
-}
-
-
-/*
- * FINISHED ... sent by both CLIENT and SERVER
- *
- * This is the FINISHED message as defined in the SSL and TLS protocols.
- * Both protocols define this handshake message slightly differently.
- * This class supports both formats.
- *
- * When handshaking is finished, each side sends a "change_cipher_spec"
- * record, then immediately sends a "finished" handshake message prepared
- * according to the newly adopted cipher spec.
- *
- * NOTE that until this is sent, no application data may be passed, unless
- * some non-default cipher suite has already been set up on this connection
- * connection (e.g. a previous handshake arranged one).
- */
-static final class Finished extends HandshakeMessage {
-
-    // constant for a Finished message sent by the client
-    final static int CLIENT = 1;
-
-    // constant for a Finished message sent by the server
-    final static int SERVER = 2;
-
-    // enum Sender:  "CLNT" and "SRVR"
-    private static final byte[] SSL_CLIENT = { 0x43, 0x4C, 0x4E, 0x54 };
-    private static final byte[] SSL_SERVER = { 0x53, 0x52, 0x56, 0x52 };
-
-    /*
-     * Contents of the finished message ("checksum"). For TLS, it
-     * is 12 bytes long, for SSLv3 36 bytes.
-     */
-    private byte[] verifyData;
-
-    /*
-     * Current cipher suite we are negotiating.  TLS 1.2 has
-     * ciphersuite-defined PRF algorithms.
-     */
-    private ProtocolVersion protocolVersion;
-    private CipherSuite cipherSuite;
-
-    /*
-     * Create a finished message to send to the remote peer.
-     */
-    Finished(ProtocolVersion protocolVersion, HandshakeHash handshakeHash,
-            int sender, SecretKey master, CipherSuite cipherSuite) {
-        this.protocolVersion = protocolVersion;
-        this.cipherSuite = cipherSuite;
-        verifyData = getFinished(handshakeHash, sender, master);
-    }
-
-    /*
-     * Constructor that reads FINISHED message from stream.
-     */
-    Finished(ProtocolVersion protocolVersion, HandshakeInStream input,
-            CipherSuite cipherSuite) throws IOException {
-        this.protocolVersion = protocolVersion;
-        this.cipherSuite = cipherSuite;
-        int msgLen = (protocolVersion.v >= ProtocolVersion.TLS10.v) ? 12 : 36;
-        verifyData = new byte[msgLen];
-        input.read(verifyData);
-    }
-
-    /*
-     * Verify that the hashes here are what would have been produced
-     * according to a given set of inputs.  This is used to ensure that
-     * both client and server are fully in sync, and that the handshake
-     * computations have been successful.
-     */
-    boolean verify(HandshakeHash handshakeHash, int sender, SecretKey master) {
-        byte[] myFinished = getFinished(handshakeHash, sender, master);
-        return Arrays.equals(myFinished, verifyData);
-    }
-
-    /*
-     * Perform the actual finished message calculation.
-     */
-    private byte[] getFinished(HandshakeHash handshakeHash,
-            int sender, SecretKey masterKey) {
-        byte[] sslLabel;
-        String tlsLabel;
-        if (sender == CLIENT) {
-            sslLabel = SSL_CLIENT;
-            tlsLabel = "client finished";
-        } else if (sender == SERVER) {
-            sslLabel = SSL_SERVER;
-            tlsLabel = "server finished";
-        } else {
-            throw new RuntimeException("Invalid sender: " + sender);
-        }
-
-        if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
-            // TLS 1.0+
-            try {
-                byte [] seed;
-                String prfAlg;
-                PRF prf;
-
-                // Get the KeyGenerator alg and calculate the seed.
-                if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                    // TLS 1.2
-                    seed = handshakeHash.getFinishedHash();
-
-                    prfAlg = "SunTls12Prf";
-                    prf = cipherSuite.prfAlg;
-                } else {
-                    // TLS 1.0/1.1
-                    MessageDigest md5Clone = handshakeHash.getMD5Clone();
-                    MessageDigest shaClone = handshakeHash.getSHAClone();
-                    seed = new byte[36];
-                    md5Clone.digest(seed, 0, 16);
-                    shaClone.digest(seed, 16, 20);
-
-                    prfAlg = "SunTlsPrf";
-                    prf = P_NONE;
-                }
-
-                String prfHashAlg = prf.getPRFHashAlg();
-                int prfHashLength = prf.getPRFHashLength();
-                int prfBlockSize = prf.getPRFBlockSize();
-
-                /*
-                 * RFC 5246/7.4.9 says that finished messages can
-                 * be ciphersuite-specific in both length/PRF hash
-                 * algorithm.  If we ever run across a different
-                 * length, this call will need to be updated.
-                 */
-                TlsPrfParameterSpec spec = new TlsPrfParameterSpec(
-                    masterKey, tlsLabel, seed, 12,
-                    prfHashAlg, prfHashLength, prfBlockSize);
-
-                KeyGenerator kg = JsseJce.getKeyGenerator(prfAlg);
-                kg.init(spec);
-                SecretKey prfKey = kg.generateKey();
-                if ("RAW".equals(prfKey.getFormat()) == false) {
-                    throw new ProviderException(
-                        "Invalid PRF output, format must be RAW");
-                }
-                byte[] finished = prfKey.getEncoded();
-                return finished;
-            } catch (GeneralSecurityException e) {
-                throw new RuntimeException("PRF failed", e);
-            }
-        } else {
-            // SSLv3
-            MessageDigest md5Clone = handshakeHash.getMD5Clone();
-            MessageDigest shaClone = handshakeHash.getSHAClone();
-            updateDigest(md5Clone, sslLabel, MD5_pad1, MD5_pad2, masterKey);
-            updateDigest(shaClone, sslLabel, SHA_pad1, SHA_pad2, masterKey);
-            byte[] finished = new byte[36];
-            try {
-                md5Clone.digest(finished, 0, 16);
-                shaClone.digest(finished, 16, 20);
-            } catch (DigestException e) {
-                // cannot occur
-                throw new RuntimeException("Digest failed", e);
-            }
-            return finished;
-        }
-    }
-
-    /*
-     * Update the MessageDigest for SSLv3 finished message calculation.
-     * The digest must already have been updated with all preceding handshake
-     * messages. This operation is almost identical to the certificate verify
-     * hash, reuse that code.
-     */
-    private static void updateDigest(MessageDigest md, byte[] sender,
-            byte[] pad1, byte[] pad2, SecretKey masterSecret) {
-        md.update(sender);
-        CertificateVerify.updateDigest(md, pad1, pad2, masterSecret);
-    }
-
-    // get the verify_data of the finished message
-    byte[] getVerifyData() {
-        return verifyData;
-    }
-
-    @Override
-    int messageType() { return ht_finished; }
-
-    @Override
-    int messageLength() {
-        return verifyData.length;
-    }
-
-    @Override
-    void send(HandshakeOutStream out) throws IOException {
-        out.write(verifyData);
-    }
-
-    @Override
-    void print(PrintStream s) throws IOException {
-        s.println("*** Finished");
-        if (debug != null && Debug.isOn("verbose")) {
-            Debug.println(s, "verify_data", verifyData);
-            s.println("***");
-        }
-    }
-}
-
-//
-// END of nested classes
-//
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/HandshakeOutStream.java b/ojluni/src/main/java/sun/security/ssl/HandshakeOutStream.java
deleted file mode 100755
index 25aeed6..0000000
--- a/ojluni/src/main/java/sun/security/ssl/HandshakeOutStream.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.OutputStream;
-import java.io.IOException;
-import java.security.MessageDigest;
-
-/**
- * Output stream for handshake data.  This is used only internally
- * to the SSL classes.
- *
- * MT note:  one thread at a time is presumed be writing handshake
- * messages, but (after initial connection setup) it's possible to
- * have other threads reading/writing application data.  It's the
- * SSLSocketImpl class that synchronizes record writes.
- *
- * @author  David Brownell
- */
-public class HandshakeOutStream extends OutputStream {
-
-    private SSLSocketImpl socket;
-    private SSLEngineImpl engine;
-
-    OutputRecord r;
-
-    HandshakeOutStream(ProtocolVersion protocolVersion,
-            ProtocolVersion helloVersion, HandshakeHash handshakeHash,
-            SSLSocketImpl socket) {
-        this.socket = socket;
-        r = new OutputRecord(Record.ct_handshake);
-        init(protocolVersion, helloVersion, handshakeHash);
-    }
-
-    HandshakeOutStream(ProtocolVersion protocolVersion,
-            ProtocolVersion helloVersion, HandshakeHash handshakeHash,
-            SSLEngineImpl engine) {
-        this.engine = engine;
-        r = new EngineOutputRecord(Record.ct_handshake, engine);
-        init(protocolVersion, helloVersion, handshakeHash);
-    }
-
-    private void init(ProtocolVersion protocolVersion,
-            ProtocolVersion helloVersion, HandshakeHash handshakeHash) {
-        r.setVersion(protocolVersion);
-        r.setHelloVersion(helloVersion);
-        r.setHandshakeHash(handshakeHash);
-    }
-
-
-    /*
-     * Update the handshake data hashes ... mostly for use after a
-     * client cert has been sent, so the cert verify message can be
-     * constructed correctly yet without forcing extra I/O.  In all
-     * other cases, automatic hash calculation suffices.
-     */
-    void doHashes() {
-        r.doHashes();
-    }
-
-    /*
-     * Write some data out onto the stream ... buffers as much as possible.
-     * Hashes are updated automatically if something gets flushed to the
-     * network (e.g. a big cert message etc).
-     */
-    public void write(byte buf[], int off, int len) throws IOException {
-        while (len > 0) {
-            int howmuch = Math.min(len, r.availableDataBytes());
-
-            if (howmuch == 0) {
-                flush();
-            } else {
-                r.write(buf, off, howmuch);
-                off += howmuch;
-                len -= howmuch;
-            }
-        }
-    }
-
-    /*
-     * write-a-byte
-     */
-    public void write(int i) throws IOException {
-        if (r.availableDataBytes() < 1) {
-            flush();
-        }
-        r.write(i);
-    }
-
-    public void flush() throws IOException {
-        if (socket != null) {
-            try {
-                socket.writeRecord(r);
-            } catch (IOException e) {
-                // Had problems writing; check if there was an
-                // alert from peer. If alert received, waitForClose
-                // will throw an exception for the alert
-                socket.waitForClose(true);
-
-                // No alert was received, just rethrow exception
-                throw e;
-            }
-        } else {  // engine != null
-            /*
-             * Even if record might be empty, flush anyway in case
-             * there is a finished handshake message that we need
-             * to queue.
-             */
-            engine.writeRecord((EngineOutputRecord)r);
-        }
-    }
-
-    /*
-     * Tell the OutputRecord that a finished message was
-     * contained either in this record or the one immeiately
-     * preceeding it.  We need to reliably pass back notifications
-     * that a finish message occured.
-     */
-    void setFinishedMsg() {
-        assert(socket == null);
-
-        ((EngineOutputRecord)r).setFinishedMsg();
-    }
-
-    /*
-     * Put integers encoded in standard 8, 16, 24, and 32 bit
-     * big endian formats. Note that OutputStream.write(int) only
-     * writes the least significant 8 bits and ignores the rest.
-     */
-
-    void putInt8(int i) throws IOException {
-        checkOverflow(i, Record.OVERFLOW_OF_INT08);
-        r.write(i);
-    }
-
-    void putInt16(int i) throws IOException {
-        checkOverflow(i, Record.OVERFLOW_OF_INT16);
-        if (r.availableDataBytes() < 2) {
-            flush();
-        }
-        r.write(i >> 8);
-        r.write(i);
-    }
-
-    void putInt24(int i) throws IOException {
-        checkOverflow(i, Record.OVERFLOW_OF_INT24);
-        if (r.availableDataBytes() < 3) {
-            flush();
-        }
-        r.write(i >> 16);
-        r.write(i >> 8);
-        r.write(i);
-    }
-
-    void putInt32(int i) throws IOException {
-        if (r.availableDataBytes() < 4) {
-            flush();
-        }
-        r.write(i >> 24);
-        r.write(i >> 16);
-        r.write(i >> 8);
-        r.write(i);
-    }
-
-    /*
-     * Put byte arrays with length encoded as 8, 16, 24 bit
-     * integers in big-endian format.
-     */
-    void putBytes8(byte b[]) throws IOException {
-        if (b == null) {
-            putInt8(0);
-            return;
-        } else {
-            checkOverflow(b.length, Record.OVERFLOW_OF_INT08);
-        }
-        putInt8(b.length);
-        write(b, 0, b.length);
-    }
-
-    public void putBytes16(byte b[]) throws IOException {
-        if (b == null) {
-            putInt16(0);
-            return;
-        } else {
-            checkOverflow(b.length, Record.OVERFLOW_OF_INT16);
-        }
-        putInt16(b.length);
-        write(b, 0, b.length);
-    }
-
-    void putBytes24(byte b[]) throws IOException {
-        if (b == null) {
-            putInt24(0);
-            return;
-        } else {
-            checkOverflow(b.length, Record.OVERFLOW_OF_INT24);
-        }
-        putInt24(b.length);
-        write(b, 0, b.length);
-    }
-
-    private void checkOverflow(int length, int overflow) {
-        if (length >= overflow) {
-            // internal_error alert will be triggered
-            throw new RuntimeException(
-                    "Field length overflow, the field length (" +
-                    length + ") should be less than " + overflow);
-        }
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/Handshaker.java b/ojluni/src/main/java/sun/security/ssl/Handshaker.java
deleted file mode 100755
index 2f1d01b..0000000
--- a/ojluni/src/main/java/sun/security/ssl/Handshaker.java
+++ /dev/null
@@ -1,1384 +0,0 @@
-/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.util.*;
-import java.security.*;
-import java.security.NoSuchAlgorithmException;
-import java.security.AccessController;
-import java.security.AlgorithmConstraints;
-import java.security.AccessControlContext;
-import java.security.PrivilegedExceptionAction;
-import java.security.PrivilegedActionException;
-
-import javax.crypto.*;
-import javax.crypto.spec.*;
-
-import javax.net.ssl.*;
-import sun.misc.HexDumpEncoder;
-
-import sun.security.internal.spec.*;
-import sun.security.internal.interfaces.TlsMasterSecret;
-
-import sun.security.ssl.HandshakeMessage.*;
-import sun.security.ssl.CipherSuite.*;
-
-import static sun.security.ssl.CipherSuite.PRF.*;
-
-/**
- * Handshaker ... processes handshake records from an SSL V3.0
- * data stream, handling all the details of the handshake protocol.
- *
- * Note that the real protocol work is done in two subclasses, the  base
- * class just provides the control flow and key generation framework.
- *
- * @author David Brownell
- */
-abstract class Handshaker {
-
-    // protocol version being established using this Handshaker
-    ProtocolVersion protocolVersion;
-
-    // the currently active protocol version during a renegotiation
-    ProtocolVersion     activeProtocolVersion;
-
-    // security parameters for secure renegotiation.
-    boolean             secureRenegotiation;
-    byte[]              clientVerifyData;
-    byte[]              serverVerifyData;
-
-    // Is it an initial negotiation  or a renegotiation?
-    boolean                     isInitialHandshake;
-
-    // List of enabled protocols
-    private ProtocolList        enabledProtocols;
-
-    // List of enabled CipherSuites
-    private CipherSuiteList     enabledCipherSuites;
-
-    // The endpoint identification protocol
-    String              identificationProtocol;
-
-    // The cryptographic algorithm constraints
-    private AlgorithmConstraints    algorithmConstraints = null;
-
-    // Local supported signature and algorithms
-    Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs;
-
-    // Peer supported signature and algorithms
-    Collection<SignatureAndHashAlgorithm> peerSupportedSignAlgs;
-
-    /*
-
-    /*
-     * List of active protocols
-     *
-     * Active protocols is a subset of enabled protocols, and will
-     * contain only those protocols that have vaild cipher suites
-     * enabled.
-     */
-    private ProtocolList       activeProtocols;
-
-    /*
-     * List of active cipher suites
-     *
-     * Active cipher suites is a subset of enabled cipher suites, and will
-     * contain only those cipher suites available for the active protocols.
-     */
-    private CipherSuiteList    activeCipherSuites;
-
-    private boolean             isClient;
-    private boolean             needCertVerify;
-
-    SSLSocketImpl               conn = null;
-    SSLEngineImpl               engine = null;
-
-    HandshakeHash               handshakeHash;
-    HandshakeInStream           input;
-    HandshakeOutStream          output;
-    int                         state;
-    SSLContextImpl              sslContext;
-    RandomCookie                clnt_random, svr_random;
-    SSLSessionImpl              session;
-
-    // current CipherSuite. Never null, initially SSL_NULL_WITH_NULL_NULL
-    CipherSuite         cipherSuite;
-
-    // current key exchange. Never null, initially K_NULL
-    KeyExchange         keyExchange;
-
-    /* True if this session is being resumed (fast handshake) */
-    boolean             resumingSession;
-
-    /* True if it's OK to start a new SSL session */
-    boolean             enableNewSession;
-
-    // Temporary storage for the individual keys. Set by
-    // calculateConnectionKeys() and cleared once the ciphers are
-    // activated.
-    private SecretKey clntWriteKey, svrWriteKey;
-    private IvParameterSpec clntWriteIV, svrWriteIV;
-    private SecretKey clntMacSecret, svrMacSecret;
-
-    /*
-     * Delegated task subsystem data structures.
-     *
-     * If thrown is set, we need to propagate this back immediately
-     * on entry into processMessage().
-     *
-     * Data is protected by the SSLEngine.this lock.
-     */
-    private volatile boolean taskDelegated = false;
-    private volatile DelegatedTask delegatedTask = null;
-    private volatile Exception thrown = null;
-
-    // Could probably use a java.util.concurrent.atomic.AtomicReference
-    // here instead of using this lock.  Consider changing.
-    private Object thrownLock = new Object();
-
-    /* Class and subclass dynamic debugging support */
-    static final Debug debug = Debug.getInstance("ssl");
-
-    // By default, disable the unsafe legacy session renegotiation
-    static final boolean allowUnsafeRenegotiation = Debug.getBooleanProperty(
-                    "sun.security.ssl.allowUnsafeRenegotiation", false);
-
-    // For maximum interoperability and backward compatibility, RFC 5746
-    // allows server (or client) to accept ClientHello (or ServerHello)
-    // message without the secure renegotiation_info extension or SCSV.
-    //
-    // For maximum security, RFC 5746 also allows server (or client) to
-    // reject such message with a fatal "handshake_failure" alert.
-    //
-    // By default, allow such legacy hello messages.
-    static final boolean allowLegacyHelloMessages = Debug.getBooleanProperty(
-                    "sun.security.ssl.allowLegacyHelloMessages", true);
-
-    // need to dispose the object when it is invalidated
-    boolean invalidated;
-
-    Handshaker(SSLSocketImpl c, SSLContextImpl context,
-            ProtocolList enabledProtocols, boolean needCertVerify,
-            boolean isClient, ProtocolVersion activeProtocolVersion,
-            boolean isInitialHandshake, boolean secureRenegotiation,
-            byte[] clientVerifyData, byte[] serverVerifyData) {
-        this.conn = c;
-        init(context, enabledProtocols, needCertVerify, isClient,
-            activeProtocolVersion, isInitialHandshake, secureRenegotiation,
-            clientVerifyData, serverVerifyData);
-    }
-
-    Handshaker(SSLEngineImpl engine, SSLContextImpl context,
-            ProtocolList enabledProtocols, boolean needCertVerify,
-            boolean isClient, ProtocolVersion activeProtocolVersion,
-            boolean isInitialHandshake, boolean secureRenegotiation,
-            byte[] clientVerifyData, byte[] serverVerifyData) {
-        this.engine = engine;
-        init(context, enabledProtocols, needCertVerify, isClient,
-            activeProtocolVersion, isInitialHandshake, secureRenegotiation,
-            clientVerifyData, serverVerifyData);
-    }
-
-    private void init(SSLContextImpl context, ProtocolList enabledProtocols,
-            boolean needCertVerify, boolean isClient,
-            ProtocolVersion activeProtocolVersion,
-            boolean isInitialHandshake, boolean secureRenegotiation,
-            byte[] clientVerifyData, byte[] serverVerifyData) {
-
-        if (debug != null && Debug.isOn("handshake")) {
-            System.out.println(
-                "Allow unsafe renegotiation: " + allowUnsafeRenegotiation +
-                "\nAllow legacy hello messages: " + allowLegacyHelloMessages +
-                "\nIs initial handshake: " + isInitialHandshake +
-                "\nIs secure renegotiation: " + secureRenegotiation);
-        }
-
-        this.sslContext = context;
-        this.isClient = isClient;
-        this.needCertVerify = needCertVerify;
-        this.activeProtocolVersion = activeProtocolVersion;
-        this.isInitialHandshake = isInitialHandshake;
-        this.secureRenegotiation = secureRenegotiation;
-        this.clientVerifyData = clientVerifyData;
-        this.serverVerifyData = serverVerifyData;
-        enableNewSession = true;
-        invalidated = false;
-
-        setCipherSuite(CipherSuite.C_NULL);
-        setEnabledProtocols(enabledProtocols);
-
-        if (conn != null) {
-            algorithmConstraints = new SSLAlgorithmConstraints(conn, true);
-        } else {        // engine != null
-            algorithmConstraints = new SSLAlgorithmConstraints(engine, true);
-        }
-
-
-        //
-        // In addition to the connection state machine, controlling
-        // how the connection deals with the different sorts of records
-        // that get sent (notably handshake transitions!), there's
-        // also a handshaking state machine that controls message
-        // sequencing.
-        //
-        // It's a convenient artifact of the protocol that this can,
-        // with only a couple of minor exceptions, be driven by the
-        // type constant for the last message seen:  except for the
-        // client's cert verify, those constants are in a convenient
-        // order to drastically simplify state machine checking.
-        //
-        state = -2;  // initialized but not activated
-    }
-
-    /*
-     * Reroutes calls to the SSLSocket or SSLEngine (*SE).
-     *
-     * We could have also done it by extra classes
-     * and letting them override, but this seemed much
-     * less involved.
-     */
-    void fatalSE(byte b, String diagnostic) throws IOException {
-        fatalSE(b, diagnostic, null);
-    }
-
-    void fatalSE(byte b, Throwable cause) throws IOException {
-        fatalSE(b, null, cause);
-    }
-
-    void fatalSE(byte b, String diagnostic, Throwable cause)
-            throws IOException {
-        if (conn != null) {
-            conn.fatal(b, diagnostic, cause);
-        } else {
-            engine.fatal(b, diagnostic, cause);
-        }
-    }
-
-    void warningSE(byte b) {
-        if (conn != null) {
-            conn.warning(b);
-        } else {
-            engine.warning(b);
-        }
-    }
-
-    String getRawHostnameSE() {
-        if (conn != null) {
-            return conn.getRawHostname();
-        } else {
-            return engine.getPeerHost();
-        }
-    }
-
-    String getHostSE() {
-        if (conn != null) {
-            return conn.getHost();
-        } else {
-            return engine.getPeerHost();
-        }
-    }
-
-    String getHostAddressSE() {
-        if (conn != null) {
-            return conn.getInetAddress().getHostAddress();
-        } else {
-            /*
-             * This is for caching only, doesn't matter that's is really
-             * a hostname.  The main thing is that it doesn't do
-             * a reverse DNS lookup, potentially slowing things down.
-             */
-            return engine.getPeerHost();
-        }
-    }
-
-    boolean isLoopbackSE() {
-        if (conn != null) {
-            return conn.getInetAddress().isLoopbackAddress();
-        } else {
-            return false;
-        }
-    }
-
-    int getPortSE() {
-        if (conn != null) {
-            return conn.getPort();
-        } else {
-            return engine.getPeerPort();
-        }
-    }
-
-    int getLocalPortSE() {
-        if (conn != null) {
-            return conn.getLocalPort();
-        } else {
-            return -1;
-        }
-    }
-
-    AccessControlContext getAccSE() {
-        if (conn != null) {
-            return conn.getAcc();
-        } else {
-            return engine.getAcc();
-        }
-    }
-
-    private void setVersionSE(ProtocolVersion protocolVersion) {
-        if (conn != null) {
-            conn.setVersion(protocolVersion);
-        } else {
-            engine.setVersion(protocolVersion);
-        }
-    }
-
-    /**
-     * Set the active protocol version and propagate it to the SSLSocket
-     * and our handshake streams. Called from ClientHandshaker
-     * and ServerHandshaker with the negotiated protocol version.
-     */
-    void setVersion(ProtocolVersion protocolVersion) {
-        this.protocolVersion = protocolVersion;
-        setVersionSE(protocolVersion);
-
-        output.r.setVersion(protocolVersion);
-    }
-
-    /**
-     * Set the enabled protocols. Called from the constructor or
-     * SSLSocketImpl/SSLEngineImpl.setEnabledProtocols() (if the
-     * handshake is not yet in progress).
-     */
-    void setEnabledProtocols(ProtocolList enabledProtocols) {
-        activeCipherSuites = null;
-        activeProtocols = null;
-
-        this.enabledProtocols = enabledProtocols;
-    }
-
-    /**
-     * Set the enabled cipher suites. Called from
-     * SSLSocketImpl/SSLEngineImpl.setEnabledCipherSuites() (if the
-     * handshake is not yet in progress).
-     */
-    void setEnabledCipherSuites(CipherSuiteList enabledCipherSuites) {
-        activeCipherSuites = null;
-        activeProtocols = null;
-        this.enabledCipherSuites = enabledCipherSuites;
-    }
-
-    /**
-     * Set the algorithm constraints. Called from the constructor or
-     * SSLSocketImpl/SSLEngineImpl.setAlgorithmConstraints() (if the
-     * handshake is not yet in progress).
-     */
-    void setAlgorithmConstraints(AlgorithmConstraints algorithmConstraints) {
-        activeCipherSuites = null;
-        activeProtocols = null;
-
-        this.algorithmConstraints =
-            new SSLAlgorithmConstraints(algorithmConstraints);
-        this.localSupportedSignAlgs = null;
-    }
-
-    Collection<SignatureAndHashAlgorithm> getLocalSupportedSignAlgs() {
-        if (localSupportedSignAlgs == null) {
-            localSupportedSignAlgs =
-                SignatureAndHashAlgorithm.getSupportedAlgorithms(
-                                                    algorithmConstraints);
-        }
-
-        return localSupportedSignAlgs;
-    }
-
-    void setPeerSupportedSignAlgs(
-            Collection<SignatureAndHashAlgorithm> algorithms) {
-        peerSupportedSignAlgs =
-            new ArrayList<SignatureAndHashAlgorithm>(algorithms);
-    }
-
-    Collection<SignatureAndHashAlgorithm> getPeerSupportedSignAlgs() {
-        return peerSupportedSignAlgs;
-    }
-
-
-    /**
-     * Set the identification protocol. Called from the constructor or
-     * SSLSocketImpl/SSLEngineImpl.setIdentificationProtocol() (if the
-     * handshake is not yet in progress).
-     */
-    void setIdentificationProtocol(String protocol) {
-        this.identificationProtocol = protocol;
-    }
-
-    /**
-     * Prior to handshaking, activate the handshake and initialize the version,
-     * input stream and output stream.
-     */
-    void activate(ProtocolVersion helloVersion) throws IOException {
-        if (activeProtocols == null) {
-            activeProtocols = getActiveProtocols();
-        }
-
-        if (activeProtocols.collection().isEmpty() ||
-                activeProtocols.max.v == ProtocolVersion.NONE.v) {
-            throw new SSLHandshakeException("No appropriate protocol");
-        }
-
-        if (activeCipherSuites == null) {
-            activeCipherSuites = getActiveCipherSuites();
-        }
-
-        if (activeCipherSuites.collection().isEmpty()) {
-            throw new SSLHandshakeException("No appropriate cipher suite");
-        }
-
-        // temporary protocol version until the actual protocol version
-        // is negotiated in the Hello exchange. This affects the record
-        // version we sent with the ClientHello.
-        if (!isInitialHandshake) {
-            protocolVersion = activeProtocolVersion;
-        } else {
-            protocolVersion = activeProtocols.max;
-        }
-
-        if (helloVersion == null || helloVersion.v == ProtocolVersion.NONE.v) {
-            helloVersion = activeProtocols.helloVersion;
-        }
-
-        // We accumulate digests of the handshake messages so that
-        // we can read/write CertificateVerify and Finished messages,
-        // getting assurance against some particular active attacks.
-        Set<String> localSupportedHashAlgorithms =
-            SignatureAndHashAlgorithm.getHashAlgorithmNames(
-                getLocalSupportedSignAlgs());
-        handshakeHash = new HandshakeHash(!isClient, needCertVerify,
-            localSupportedHashAlgorithms);
-
-        // Generate handshake input/output stream.
-        input = new HandshakeInStream(handshakeHash);
-        if (conn != null) {
-            output = new HandshakeOutStream(protocolVersion, helloVersion,
-                                        handshakeHash, conn);
-            conn.getAppInputStream().r.setHandshakeHash(handshakeHash);
-            conn.getAppInputStream().r.setHelloVersion(helloVersion);
-            conn.getAppOutputStream().r.setHelloVersion(helloVersion);
-        } else {
-            output = new HandshakeOutStream(protocolVersion, helloVersion,
-                                        handshakeHash, engine);
-            engine.inputRecord.setHandshakeHash(handshakeHash);
-            engine.inputRecord.setHelloVersion(helloVersion);
-            engine.outputRecord.setHelloVersion(helloVersion);
-        }
-
-        // move state to activated
-        state = -1;
-    }
-
-    /**
-     * Set cipherSuite and keyExchange to the given CipherSuite.
-     * Does not perform any verification that this is a valid selection,
-     * this must be done before calling this method.
-     */
-    void setCipherSuite(CipherSuite s) {
-        this.cipherSuite = s;
-        this.keyExchange = s.keyExchange;
-    }
-
-    /**
-     * Check if the given ciphersuite is enabled and available.
-     * Does not check if the required server certificates are available.
-     */
-    boolean isNegotiable(CipherSuite s) {
-        if (activeCipherSuites == null) {
-            activeCipherSuites = getActiveCipherSuites();
-        }
-
-        return activeCipherSuites.contains(s) && s.isNegotiable();
-    }
-
-    /**
-     * Check if the given protocol version is enabled and available.
-     */
-    boolean isNegotiable(ProtocolVersion protocolVersion) {
-        if (activeProtocols == null) {
-            activeProtocols = getActiveProtocols();
-        }
-
-        return activeProtocols.contains(protocolVersion);
-    }
-
-    /**
-     * Select a protocol version from the list. Called from
-     * ServerHandshaker to negotiate protocol version.
-     *
-     * Return the lower of the protocol version suggested in the
-     * clien hello and the highest supported by the server.
-     */
-    ProtocolVersion selectProtocolVersion(ProtocolVersion protocolVersion) {
-        if (activeProtocols == null) {
-            activeProtocols = getActiveProtocols();
-        }
-
-        return activeProtocols.selectProtocolVersion(protocolVersion);
-    }
-
-    /**
-     * Get the active cipher suites.
-     *
-     * In TLS 1.1, many weak or vulnerable cipher suites were obsoleted,
-     * such as TLS_RSA_EXPORT_WITH_RC4_40_MD5. The implementation MUST NOT
-     * negotiate these cipher suites in TLS 1.1 or later mode.
-     *
-     * Therefore, when the active protocols only include TLS 1.1 or later,
-     * the client cannot request to negotiate those obsoleted cipher
-     * suites.  That is, the obsoleted suites should not be included in the
-     * client hello. So we need to create a subset of the enabled cipher
-     * suites, the active cipher suites, which does not contain obsoleted
-     * cipher suites of the minimum active protocol.
-     *
-     * Return empty list instead of null if no active cipher suites.
-     */
-    CipherSuiteList getActiveCipherSuites() {
-        if (activeCipherSuites == null) {
-            if (activeProtocols == null) {
-                activeProtocols = getActiveProtocols();
-            }
-
-            ArrayList<CipherSuite> suites = new ArrayList<>();
-            if (!(activeProtocols.collection().isEmpty()) &&
-                    activeProtocols.min.v != ProtocolVersion.NONE.v) {
-                for (CipherSuite suite : enabledCipherSuites.collection()) {
-                    if (suite.obsoleted > activeProtocols.min.v &&
-                            suite.supported <= activeProtocols.max.v) {
-                        if (algorithmConstraints.permits(
-                                EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
-                                suite.name, null)) {
-                            suites.add(suite);
-                        }
-                    } else if (debug != null && Debug.isOn("verbose")) {
-                        if (suite.obsoleted <= activeProtocols.min.v) {
-                            System.out.println(
-                                "Ignoring obsoleted cipher suite: " + suite);
-                        } else {
-                            System.out.println(
-                                "Ignoring unsupported cipher suite: " + suite);
-                        }
-                    }
-                }
-            }
-            activeCipherSuites = new CipherSuiteList(suites);
-        }
-
-        return activeCipherSuites;
-    }
-
-    /*
-     * Get the active protocol versions.
-     *
-     * In TLS 1.1, many weak or vulnerable cipher suites were obsoleted,
-     * such as TLS_RSA_EXPORT_WITH_RC4_40_MD5. The implementation MUST NOT
-     * negotiate these cipher suites in TLS 1.1 or later mode.
-     *
-     * For example, if "TLS_RSA_EXPORT_WITH_RC4_40_MD5" is the
-     * only enabled cipher suite, the client cannot request TLS 1.1 or
-     * later, even though TLS 1.1 or later is enabled.  We need to create a
-     * subset of the enabled protocols, called the active protocols, which
-     * contains protocols appropriate to the list of enabled Ciphersuites.
-     *
-     * Return empty list instead of null if no active protocol versions.
-     */
-    ProtocolList getActiveProtocols() {
-        if (activeProtocols == null) {
-            ArrayList<ProtocolVersion> protocols = new ArrayList<>(4);
-            for (ProtocolVersion protocol : enabledProtocols.collection()) {
-                boolean found = false;
-                for (CipherSuite suite : enabledCipherSuites.collection()) {
-                    if (suite.isAvailable() && suite.obsoleted > protocol.v &&
-                                               suite.supported <= protocol.v) {
-                        if (algorithmConstraints.permits(
-                                EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
-                                suite.name, null)) {
-                            protocols.add(protocol);
-                            found = true;
-                            break;
-                        } else if (debug != null && Debug.isOn("verbose")) {
-                            System.out.println(
-                                "Ignoring disabled cipher suite: " + suite +
-                                 " for " + protocol);
-                        }
-                    } else if (debug != null && Debug.isOn("verbose")) {
-                        System.out.println(
-                            "Ignoring unsupported cipher suite: " + suite +
-                                 " for " + protocol);
-                    }
-                }
-                if (!found && (debug != null) && Debug.isOn("handshake")) {
-                    System.out.println(
-                        "No available cipher suite for " + protocol);
-                }
-            }
-            activeProtocols = new ProtocolList(protocols);
-        }
-
-        return activeProtocols;
-    }
-
-    /**
-     * As long as handshaking has not activated, we can
-     * change whether session creations are allowed.
-     *
-     * Callers should do their own checking if handshaking
-     * has activated.
-     */
-    void setEnableSessionCreation(boolean newSessions) {
-        enableNewSession = newSessions;
-    }
-
-    /**
-     * Create a new read cipher and return it to caller.
-     */
-    CipherBox newReadCipher() throws NoSuchAlgorithmException {
-        BulkCipher cipher = cipherSuite.cipher;
-        CipherBox box;
-        if (isClient) {
-            box = cipher.newCipher(protocolVersion, svrWriteKey, svrWriteIV,
-                                   sslContext.getSecureRandom(), false);
-            svrWriteKey = null;
-            svrWriteIV = null;
-        } else {
-            box = cipher.newCipher(protocolVersion, clntWriteKey, clntWriteIV,
-                                   sslContext.getSecureRandom(), false);
-            clntWriteKey = null;
-            clntWriteIV = null;
-        }
-        return box;
-    }
-
-    /**
-     * Create a new write cipher and return it to caller.
-     */
-    CipherBox newWriteCipher() throws NoSuchAlgorithmException {
-        BulkCipher cipher = cipherSuite.cipher;
-        CipherBox box;
-        if (isClient) {
-            box = cipher.newCipher(protocolVersion, clntWriteKey, clntWriteIV,
-                                   sslContext.getSecureRandom(), true);
-            clntWriteKey = null;
-            clntWriteIV = null;
-        } else {
-            box = cipher.newCipher(protocolVersion, svrWriteKey, svrWriteIV,
-                                   sslContext.getSecureRandom(), true);
-            svrWriteKey = null;
-            svrWriteIV = null;
-        }
-        return box;
-    }
-
-    /**
-     * Create a new read MAC and return it to caller.
-     */
-    MAC newReadMAC() throws NoSuchAlgorithmException, InvalidKeyException {
-        MacAlg macAlg = cipherSuite.macAlg;
-        MAC mac;
-        if (isClient) {
-            mac = macAlg.newMac(protocolVersion, svrMacSecret);
-            svrMacSecret = null;
-        } else {
-            mac = macAlg.newMac(protocolVersion, clntMacSecret);
-            clntMacSecret = null;
-        }
-        return mac;
-    }
-
-    /**
-     * Create a new write MAC and return it to caller.
-     */
-    MAC newWriteMAC() throws NoSuchAlgorithmException, InvalidKeyException {
-        MacAlg macAlg = cipherSuite.macAlg;
-        MAC mac;
-        if (isClient) {
-            mac = macAlg.newMac(protocolVersion, clntMacSecret);
-            clntMacSecret = null;
-        } else {
-            mac = macAlg.newMac(protocolVersion, svrMacSecret);
-            svrMacSecret = null;
-        }
-        return mac;
-    }
-
-    /*
-     * Returns true iff the handshake sequence is done, so that
-     * this freshly created session can become the current one.
-     */
-    boolean isDone() {
-        return state == HandshakeMessage.ht_finished;
-    }
-
-
-    /*
-     * Returns the session which was created through this
-     * handshake sequence ... should be called after isDone()
-     * returns true.
-     */
-    SSLSessionImpl getSession() {
-        return session;
-    }
-
-    /*
-     * Set the handshake session
-     */
-    void setHandshakeSessionSE(SSLSessionImpl handshakeSession) {
-        if (conn != null) {
-            conn.setHandshakeSession(handshakeSession);
-        } else {
-            engine.setHandshakeSession(handshakeSession);
-        }
-    }
-
-    /*
-     * Returns true if renegotiation is in use for this connection.
-     */
-    boolean isSecureRenegotiation() {
-        return secureRenegotiation;
-    }
-
-    /*
-     * Returns the verify_data from the Finished message sent by the client.
-     */
-    byte[] getClientVerifyData() {
-        return clientVerifyData;
-    }
-
-    /*
-     * Returns the verify_data from the Finished message sent by the server.
-     */
-    byte[] getServerVerifyData() {
-        return serverVerifyData;
-    }
-
-    /*
-     * This routine is fed SSL handshake records when they become available,
-     * and processes messages found therein.
-     */
-    void process_record(InputRecord r, boolean expectingFinished)
-            throws IOException {
-
-        checkThrown();
-
-        /*
-         * Store the incoming handshake data, then see if we can
-         * now process any completed handshake messages
-         */
-        input.incomingRecord(r);
-
-        /*
-         * We don't need to create a separate delegatable task
-         * for finished messages.
-         */
-        if ((conn != null) || expectingFinished) {
-            processLoop();
-        } else {
-            delegateTask(new PrivilegedExceptionAction<Void>() {
-                public Void run() throws Exception {
-                    processLoop();
-                    return null;
-                }
-            });
-        }
-    }
-
-    /*
-     * On input, we hash messages one at a time since servers may need
-     * to access an intermediate hash to validate a CertificateVerify
-     * message.
-     *
-     * Note that many handshake messages can come in one record (and often
-     * do, to reduce network resource utilization), and one message can also
-     * require multiple records (e.g. very large Certificate messages).
-     */
-    void processLoop() throws IOException {
-
-        // need to read off 4 bytes at least to get the handshake
-        // message type and length.
-        while (input.available() >= 4) {
-            byte messageType;
-            int messageLen;
-
-            /*
-             * See if we can read the handshake message header, and
-             * then the entire handshake message.  If not, wait till
-             * we can read and process an entire message.
-             */
-            input.mark(4);
-
-            messageType = (byte)input.getInt8();
-            messageLen = input.getInt24();
-
-            if (input.available() < messageLen) {
-                input.reset();
-                return;
-            }
-
-            /*
-             * Process the messsage.  We require
-             * that processMessage() consumes the entire message.  In
-             * lieu of explicit error checks (how?!) we assume that the
-             * data will look like garbage on encoding/processing errors,
-             * and that other protocol code will detect such errors.
-             *
-             * Note that digesting is normally deferred till after the
-             * message has been processed, though to process at least the
-             * client's Finished message (i.e. send the server's) we need
-             * to acccelerate that digesting.
-             *
-             * Also, note that hello request messages are never hashed;
-             * that includes the hello request header, too.
-             */
-            if (messageType == HandshakeMessage.ht_hello_request) {
-                input.reset();
-                processMessage(messageType, messageLen);
-                input.ignore(4 + messageLen);
-            } else {
-                input.mark(messageLen);
-                processMessage(messageType, messageLen);
-                input.digestNow();
-            }
-        }
-    }
-
-
-    /**
-     * Returns true iff the handshaker has been activated.
-     *
-     * In activated state, the handshaker may not send any messages out.
-     */
-    boolean activated() {
-        return state >= -1;
-    }
-
-    /**
-     * Returns true iff the handshaker has sent any messages.
-     */
-    boolean started() {
-        return state >= 0;  // 0: HandshakeMessage.ht_hello_request
-                            // 1: HandshakeMessage.ht_client_hello
-    }
-
-
-    /*
-     * Used to kickstart the negotiation ... either writing a
-     * ClientHello or a HelloRequest as appropriate, whichever
-     * the subclass returns.  NOP if handshaking's already started.
-     */
-    void kickstart() throws IOException {
-        if (state >= 0) {
-            return;
-        }
-
-        HandshakeMessage m = getKickstartMessage();
-
-        if (debug != null && Debug.isOn("handshake")) {
-            m.print(System.out);
-        }
-        m.write(output);
-        output.flush();
-
-        state = m.messageType();
-    }
-
-    /**
-     * Both client and server modes can start handshaking; but the
-     * message they send to do so is different.
-     */
-    abstract HandshakeMessage getKickstartMessage() throws SSLException;
-
-    /*
-     * Client and Server side protocols are each driven though this
-     * call, which processes a single message and drives the appropriate
-     * side of the protocol state machine (depending on the subclass).
-     */
-    abstract void processMessage(byte messageType, int messageLen)
-        throws IOException;
-
-    /*
-     * Most alerts in the protocol relate to handshaking problems.
-     * Alerts are detected as the connection reads data.
-     */
-    abstract void handshakeAlert(byte description) throws SSLProtocolException;
-
-    /*
-     * Sends a change cipher spec message and updates the write side
-     * cipher state so that future messages use the just-negotiated spec.
-     */
-    void sendChangeCipherSpec(Finished mesg, boolean lastMessage)
-            throws IOException {
-
-        output.flush(); // i.e. handshake data
-
-        /*
-         * The write cipher state is protected by the connection write lock
-         * so we must grab it while making the change. We also
-         * make sure no writes occur between sending the ChangeCipherSpec
-         * message, installing the new cipher state, and sending the
-         * Finished message.
-         *
-         * We already hold SSLEngine/SSLSocket "this" by virtue
-         * of this being called from the readRecord code.
-         */
-        OutputRecord r;
-        if (conn != null) {
-            r = new OutputRecord(Record.ct_change_cipher_spec);
-        } else {
-            r = new EngineOutputRecord(Record.ct_change_cipher_spec, engine);
-        }
-
-        r.setVersion(protocolVersion);
-        r.write(1);     // single byte of data
-
-        if (conn != null) {
-            conn.writeLock.lock();
-            try {
-                conn.writeRecord(r);
-                conn.changeWriteCiphers();
-                if (debug != null && Debug.isOn("handshake")) {
-                    mesg.print(System.out);
-                }
-                mesg.write(output);
-                output.flush();
-            } finally {
-                conn.writeLock.unlock();
-            }
-        } else {
-            synchronized (engine.writeLock) {
-                engine.writeRecord((EngineOutputRecord)r);
-                engine.changeWriteCiphers();
-                if (debug != null && Debug.isOn("handshake")) {
-                    mesg.print(System.out);
-                }
-                mesg.write(output);
-
-                if (lastMessage) {
-                    output.setFinishedMsg();
-                }
-                output.flush();
-            }
-        }
-    }
-
-    /*
-     * Single access point to key calculation logic.  Given the
-     * pre-master secret and the nonces from client and server,
-     * produce all the keying material to be used.
-     */
-    void calculateKeys(SecretKey preMasterSecret, ProtocolVersion version) {
-        SecretKey master = calculateMasterSecret(preMasterSecret, version);
-        session.setMasterSecret(master);
-        calculateConnectionKeys(master);
-    }
-
-
-    /*
-     * Calculate the master secret from its various components.  This is
-     * used for key exchange by all cipher suites.
-     *
-     * The master secret is the catenation of three MD5 hashes, each
-     * consisting of the pre-master secret and a SHA1 hash.  Those three
-     * SHA1 hashes are of (different) constant strings, the pre-master
-     * secret, and the nonces provided by the client and the server.
-     */
-    private SecretKey calculateMasterSecret(SecretKey preMasterSecret,
-            ProtocolVersion requestedVersion) {
-
-        if (debug != null && Debug.isOn("keygen")) {
-            HexDumpEncoder      dump = new HexDumpEncoder();
-
-            System.out.println("SESSION KEYGEN:");
-
-            System.out.println("PreMaster Secret:");
-            printHex(dump, preMasterSecret.getEncoded());
-
-            // Nonces are dumped with connection keygen, no
-            // benefit to doing it twice
-        }
-
-        // What algs/params do we need to use?
-        String masterAlg;
-        PRF prf;
-
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            masterAlg = "SunTls12MasterSecret";
-            prf = cipherSuite.prfAlg;
-        } else {
-            masterAlg = "SunTlsMasterSecret";
-            prf = P_NONE;
-        }
-
-        String prfHashAlg = prf.getPRFHashAlg();
-        int prfHashLength = prf.getPRFHashLength();
-        int prfBlockSize = prf.getPRFBlockSize();
-
-        TlsMasterSecretParameterSpec spec = new TlsMasterSecretParameterSpec(
-                preMasterSecret, protocolVersion.major, protocolVersion.minor,
-                clnt_random.random_bytes, svr_random.random_bytes,
-                prfHashAlg, prfHashLength, prfBlockSize);
-
-        SecretKey masterSecret;
-        try {
-            KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg);
-            kg.init(spec);
-            masterSecret = kg.generateKey();
-        } catch (GeneralSecurityException e) {
-            // For RSA premaster secrets, do not signal a protocol error
-            // due to the Bleichenbacher attack. See comments further down.
-            if (!preMasterSecret.getAlgorithm().equals(
-                    "TlsRsaPremasterSecret")) {
-                throw new ProviderException(e);
-            }
-
-            if (debug != null && Debug.isOn("handshake")) {
-                System.out.println("RSA master secret generation error:");
-                e.printStackTrace(System.out);
-            }
-
-            if (requestedVersion != null) {
-                preMasterSecret =
-                    RSAClientKeyExchange.generateDummySecret(requestedVersion);
-            } else {
-                preMasterSecret =
-                    RSAClientKeyExchange.generateDummySecret(protocolVersion);
-            }
-
-            // recursive call with new premaster secret
-            return calculateMasterSecret(preMasterSecret, null);
-        }
-
-        // if no version check requested (client side handshake), or version
-        // information is not available (not an RSA premaster secret),
-        // return master secret immediately.
-        if ((requestedVersion == null) ||
-                !(masterSecret instanceof TlsMasterSecret)) {
-            return masterSecret;
-        }
-
-        // we have checked the ClientKeyExchange message when reading TLS
-        // record, the following check is necessary to ensure that
-        // JCE provider does not ignore the checking, or the previous
-        // checking process bypassed the premaster secret version checking.
-        TlsMasterSecret tlsKey = (TlsMasterSecret)masterSecret;
-        int major = tlsKey.getMajorVersion();
-        int minor = tlsKey.getMinorVersion();
-        if ((major < 0) || (minor < 0)) {
-            return masterSecret;
-        }
-
-        // check if the premaster secret version is ok
-        // the specification says that it must be the maximum version supported
-        // by the client from its ClientHello message. However, many
-        // implementations send the negotiated version, so accept both
-        // for SSL v3.0 and TLS v1.0.
-        // NOTE that we may be comparing two unsupported version numbers, which
-        // is why we cannot use object reference equality in this special case.
-        ProtocolVersion premasterVersion =
-                                    ProtocolVersion.valueOf(major, minor);
-        boolean versionMismatch = (premasterVersion.v != requestedVersion.v);
-
-        /*
-         * we never checked the client_version in server side
-         * for TLS v1.0 and SSL v3.0. For compatibility, we
-         * maintain this behavior.
-         */
-        if (versionMismatch && requestedVersion.v <= ProtocolVersion.TLS10.v) {
-            versionMismatch = (premasterVersion.v != protocolVersion.v);
-        }
-
-        if (versionMismatch == false) {
-            // check passed, return key
-            return masterSecret;
-        }
-
-        // Due to the Bleichenbacher attack, do not signal a protocol error.
-        // Generate a random premaster secret and continue with the handshake,
-        // which will fail when verifying the finished messages.
-        // For more information, see comments in PreMasterSecret.
-        if (debug != null && Debug.isOn("handshake")) {
-            System.out.println("RSA PreMasterSecret version error: expected"
-                + protocolVersion + " or " + requestedVersion + ", decrypted: "
-                + premasterVersion);
-        }
-        preMasterSecret =
-            RSAClientKeyExchange.generateDummySecret(requestedVersion);
-
-        // recursive call with new premaster secret
-        return calculateMasterSecret(preMasterSecret, null);
-    }
-
-    /*
-     * Calculate the keys needed for this connection, once the session's
-     * master secret has been calculated.  Uses the master key and nonces;
-     * the amount of keying material generated is a function of the cipher
-     * suite that's been negotiated.
-     *
-     * This gets called both on the "full handshake" (where we exchanged
-     * a premaster secret and started a new session) as well as on the
-     * "fast handshake" (where we just resumed a pre-existing session).
-     */
-    void calculateConnectionKeys(SecretKey masterKey) {
-        /*
-         * For both the read and write sides of the protocol, we use the
-         * master to generate MAC secrets and cipher keying material.  Block
-         * ciphers need initialization vectors, which we also generate.
-         *
-         * First we figure out how much keying material is needed.
-         */
-        int hashSize = cipherSuite.macAlg.size;
-        boolean is_exportable = cipherSuite.exportable;
-        BulkCipher cipher = cipherSuite.cipher;
-        int expandedKeySize = is_exportable ? cipher.expandedKeySize : 0;
-
-        // Which algs/params do we need to use?
-        String keyMaterialAlg;
-        PRF prf;
-
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            keyMaterialAlg = "SunTls12KeyMaterial";
-            prf = cipherSuite.prfAlg;
-        } else {
-            keyMaterialAlg = "SunTlsKeyMaterial";
-            prf = P_NONE;
-        }
-
-        String prfHashAlg = prf.getPRFHashAlg();
-        int prfHashLength = prf.getPRFHashLength();
-        int prfBlockSize = prf.getPRFBlockSize();
-
-        TlsKeyMaterialParameterSpec spec = new TlsKeyMaterialParameterSpec(
-            masterKey, protocolVersion.major, protocolVersion.minor,
-            clnt_random.random_bytes, svr_random.random_bytes,
-            cipher.algorithm, cipher.keySize, expandedKeySize,
-            cipher.ivSize, hashSize,
-            prfHashAlg, prfHashLength, prfBlockSize);
-
-        try {
-            KeyGenerator kg = JsseJce.getKeyGenerator(keyMaterialAlg);
-            kg.init(spec);
-            TlsKeyMaterialSpec keySpec = (TlsKeyMaterialSpec)kg.generateKey();
-
-            clntWriteKey = keySpec.getClientCipherKey();
-            svrWriteKey = keySpec.getServerCipherKey();
-
-            // Return null if IVs are not supposed to be generated.
-            // e.g. TLS 1.1+.
-            clntWriteIV = keySpec.getClientIv();
-            svrWriteIV = keySpec.getServerIv();
-
-            clntMacSecret = keySpec.getClientMacKey();
-            svrMacSecret = keySpec.getServerMacKey();
-        } catch (GeneralSecurityException e) {
-            throw new ProviderException(e);
-        }
-
-        //
-        // Dump the connection keys as they're generated.
-        //
-        if (debug != null && Debug.isOn("keygen")) {
-            synchronized (System.out) {
-                HexDumpEncoder  dump = new HexDumpEncoder();
-
-                System.out.println("CONNECTION KEYGEN:");
-
-                // Inputs:
-                System.out.println("Client Nonce:");
-                printHex(dump, clnt_random.random_bytes);
-                System.out.println("Server Nonce:");
-                printHex(dump, svr_random.random_bytes);
-                System.out.println("Master Secret:");
-                printHex(dump, masterKey.getEncoded());
-
-                // Outputs:
-                System.out.println("Client MAC write Secret:");
-                printHex(dump, clntMacSecret.getEncoded());
-                System.out.println("Server MAC write Secret:");
-                printHex(dump, svrMacSecret.getEncoded());
-
-                if (clntWriteKey != null) {
-                    System.out.println("Client write key:");
-                    printHex(dump, clntWriteKey.getEncoded());
-                    System.out.println("Server write key:");
-                    printHex(dump, svrWriteKey.getEncoded());
-                } else {
-                    System.out.println("... no encryption keys used");
-                }
-
-                if (clntWriteIV != null) {
-                    System.out.println("Client write IV:");
-                    printHex(dump, clntWriteIV.getIV());
-                    System.out.println("Server write IV:");
-                    printHex(dump, svrWriteIV.getIV());
-                } else {
-                    if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
-                        System.out.println(
-                                "... no IV derived for this protocol");
-                    } else {
-                        System.out.println("... no IV used for this cipher");
-                    }
-                }
-                System.out.flush();
-            }
-        }
-    }
-
-    private static void printHex(HexDumpEncoder dump, byte[] bytes) {
-        if (bytes == null) {
-            System.out.println("(key bytes not available)");
-        } else {
-            try {
-                dump.encodeBuffer(bytes, System.out);
-            } catch (IOException e) {
-                // just for debugging, ignore this
-            }
-        }
-    }
-
-    /**
-     * Throw an SSLException with the specified message and cause.
-     * Shorthand until a new SSLException constructor is added.
-     * This method never returns.
-     */
-    static void throwSSLException(String msg, Throwable cause)
-            throws SSLException {
-        SSLException e = new SSLException(msg);
-        e.initCause(cause);
-        throw e;
-    }
-
-
-    /*
-     * Implement a simple task delegator.
-     *
-     * We are currently implementing this as a single delegator, may
-     * try for parallel tasks later.  Client Authentication could
-     * benefit from this, where ClientKeyExchange/CertificateVerify
-     * could be carried out in parallel.
-     */
-    class DelegatedTask<E> implements Runnable {
-
-        private PrivilegedExceptionAction<E> pea;
-
-        DelegatedTask(PrivilegedExceptionAction<E> pea) {
-            this.pea = pea;
-        }
-
-        public void run() {
-            synchronized (engine) {
-                try {
-                    AccessController.doPrivileged(pea, engine.getAcc());
-                } catch (PrivilegedActionException pae) {
-                    thrown = pae.getException();
-                } catch (RuntimeException rte) {
-                    thrown = rte;
-                }
-                delegatedTask = null;
-                taskDelegated = false;
-            }
-        }
-    }
-
-    private <T> void delegateTask(PrivilegedExceptionAction<T> pea) {
-        delegatedTask = new DelegatedTask<T>(pea);
-        taskDelegated = false;
-        thrown = null;
-    }
-
-    DelegatedTask getTask() {
-        if (!taskDelegated) {
-            taskDelegated = true;
-            return delegatedTask;
-        } else {
-            return null;
-        }
-    }
-
-    /*
-     * See if there are any tasks which need to be delegated
-     *
-     * Locked by SSLEngine.this.
-     */
-    boolean taskOutstanding() {
-        return (delegatedTask != null);
-    }
-
-    /*
-     * The previous caller failed for some reason, report back the
-     * Exception.  We won't worry about Error's.
-     *
-     * Locked by SSLEngine.this.
-     */
-    void checkThrown() throws SSLException {
-        synchronized (thrownLock) {
-            if (thrown != null) {
-
-                String msg = thrown.getMessage();
-
-                if (msg == null) {
-                    msg = "Delegated task threw Exception/Error";
-                }
-
-                /*
-                 * See what the underlying type of exception is.  We should
-                 * throw the same thing.  Chain thrown to the new exception.
-                 */
-                Exception e = thrown;
-                thrown = null;
-
-                if (e instanceof RuntimeException) {
-                    throw (RuntimeException)
-                        new RuntimeException(msg).initCause(e);
-                } else if (e instanceof SSLHandshakeException) {
-                    throw (SSLHandshakeException)
-                        new SSLHandshakeException(msg).initCause(e);
-                } else if (e instanceof SSLKeyException) {
-                    throw (SSLKeyException)
-                        new SSLKeyException(msg).initCause(e);
-                } else if (e instanceof SSLPeerUnverifiedException) {
-                    throw (SSLPeerUnverifiedException)
-                        new SSLPeerUnverifiedException(msg).initCause(e);
-                } else if (e instanceof SSLProtocolException) {
-                    throw (SSLProtocolException)
-                        new SSLProtocolException(msg).initCause(e);
-                } else {
-                    /*
-                     * If it's SSLException or any other Exception,
-                     * we'll wrap it in an SSLException.
-                     */
-                    throw (SSLException)
-                        new SSLException(msg).initCause(e);
-                }
-            }
-        }
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/HelloExtensions.java b/ojluni/src/main/java/sun/security/ssl/HelloExtensions.java
deleted file mode 100755
index 9db6927..0000000
--- a/ojluni/src/main/java/sun/security/ssl/HelloExtensions.java
+++ /dev/null
@@ -1,866 +0,0 @@
-/*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.*;
-
-import java.security.spec.ECParameterSpec;
-
-import javax.net.ssl.SSLProtocolException;
-
-/**
- * This file contains all the classes relevant to TLS Extensions for the
- * ClientHello and ServerHello messages. The extension mechanism and
- * several extensions are defined in RFC 3546. Additional extensions are
- * defined in the ECC RFC 4492.
- *
- * Currently, only the two ECC extensions are fully supported.
- *
- * The classes contained in this file are:
- *  . HelloExtensions: a List of extensions as used in the client hello
- *      and server hello messages.
- *  . ExtensionType: an enum style class for the extension type
- *  . HelloExtension: abstract base class for all extensions. All subclasses
- *      must be immutable.
- *
- *  . UnknownExtension: used to represent all parsed extensions that we do not
- *      explicitly support.
- *  . ServerNameExtension: the server_name extension.
- *  . SignatureAlgorithmsExtension: the signature_algorithms extension.
- *  . SupportedEllipticCurvesExtension: the ECC supported curves extension.
- *  . SupportedEllipticPointFormatsExtension: the ECC supported point formats
- *      (compressed/uncompressed) extension.
- *
- * @since   1.6
- * @author  Andreas Sterbenz
- */
-final class HelloExtensions {
-
-    private List<HelloExtension> extensions;
-    private int encodedLength;
-
-    HelloExtensions() {
-        extensions = Collections.emptyList();
-    }
-
-    HelloExtensions(HandshakeInStream s) throws IOException {
-        int len = s.getInt16();
-        extensions = new ArrayList<HelloExtension>();
-        encodedLength = len + 2;
-        while (len > 0) {
-            int type = s.getInt16();
-            int extlen = s.getInt16();
-            ExtensionType extType = ExtensionType.get(type);
-            HelloExtension extension;
-            if (extType == ExtensionType.EXT_SERVER_NAME) {
-                extension = new ServerNameExtension(s, extlen);
-            } else if (extType == ExtensionType.EXT_SIGNATURE_ALGORITHMS) {
-                extension = new SignatureAlgorithmsExtension(s, extlen);
-            } else if (extType == ExtensionType.EXT_ELLIPTIC_CURVES) {
-                extension = new SupportedEllipticCurvesExtension(s, extlen);
-            } else if (extType == ExtensionType.EXT_EC_POINT_FORMATS) {
-                extension =
-                        new SupportedEllipticPointFormatsExtension(s, extlen);
-            } else if (extType == ExtensionType.EXT_RENEGOTIATION_INFO) {
-                extension = new RenegotiationInfoExtension(s, extlen);
-            } else {
-                extension = new UnknownExtension(s, extlen, extType);
-            }
-            extensions.add(extension);
-            len -= extlen + 4;
-        }
-        if (len != 0) {
-            throw new SSLProtocolException(
-                        "Error parsing extensions: extra data");
-        }
-    }
-
-    // Return the List of extensions. Must not be modified by the caller.
-    List<HelloExtension> list() {
-        return extensions;
-    }
-
-    void add(HelloExtension ext) {
-        if (extensions.isEmpty()) {
-            extensions = new ArrayList<HelloExtension>();
-        }
-        extensions.add(ext);
-        encodedLength = -1;
-    }
-
-    HelloExtension get(ExtensionType type) {
-        for (HelloExtension ext : extensions) {
-            if (ext.type == type) {
-                return ext;
-            }
-        }
-        return null;
-    }
-
-    int length() {
-        if (encodedLength >= 0) {
-            return encodedLength;
-        }
-        if (extensions.isEmpty()) {
-            encodedLength = 0;
-        } else {
-            encodedLength = 2;
-            for (HelloExtension ext : extensions) {
-                encodedLength += ext.length();
-            }
-        }
-        return encodedLength;
-    }
-
-    void send(HandshakeOutStream s) throws IOException {
-        int length = length();
-        if (length == 0) {
-            return;
-        }
-        s.putInt16(length - 2);
-        for (HelloExtension ext : extensions) {
-            ext.send(s);
-        }
-    }
-
-    void print(PrintStream s) throws IOException {
-        for (HelloExtension ext : extensions) {
-            s.println(ext.toString());
-        }
-    }
-}
-
-final class ExtensionType {
-
-    final int id;
-    final String name;
-
-    private ExtensionType(int id, String name) {
-        this.id = id;
-        this.name = name;
-    }
-
-    public String toString() {
-        return name;
-    }
-
-    static List<ExtensionType> knownExtensions = new ArrayList<>(9);
-
-    static ExtensionType get(int id) {
-        for (ExtensionType ext : knownExtensions) {
-            if (ext.id == id) {
-                return ext;
-            }
-        }
-        return new ExtensionType(id, "type_" + id);
-    }
-
-    private static ExtensionType e(int id, String name) {
-        ExtensionType ext = new ExtensionType(id, name);
-        knownExtensions.add(ext);
-        return ext;
-    }
-
-    // extensions defined in RFC 3546
-    final static ExtensionType EXT_SERVER_NAME =
-            e(0x0000, "server_name");            // IANA registry value: 0
-    final static ExtensionType EXT_MAX_FRAGMENT_LENGTH =
-            e(0x0001, "max_fragment_length");    // IANA registry value: 1
-    final static ExtensionType EXT_CLIENT_CERTIFICATE_URL =
-            e(0x0002, "client_certificate_url"); // IANA registry value: 2
-    final static ExtensionType EXT_TRUSTED_CA_KEYS =
-            e(0x0003, "trusted_ca_keys");        // IANA registry value: 3
-    final static ExtensionType EXT_TRUNCATED_HMAC =
-            e(0x0004, "truncated_hmac");         // IANA registry value: 4
-    final static ExtensionType EXT_STATUS_REQUEST =
-            e(0x0005, "status_request");         // IANA registry value: 5
-
-    // extensions defined in RFC 4681
-    final static ExtensionType EXT_USER_MAPPING =
-            e(0x0006, "user_mapping");           // IANA registry value: 6
-
-    // extensions defined in RFC 5081
-    final static ExtensionType EXT_CERT_TYPE =
-            e(0x0009, "cert_type");              // IANA registry value: 9
-
-    // extensions defined in RFC 4492 (ECC)
-    final static ExtensionType EXT_ELLIPTIC_CURVES =
-            e(0x000A, "elliptic_curves");        // IANA registry value: 10
-    final static ExtensionType EXT_EC_POINT_FORMATS =
-            e(0x000B, "ec_point_formats");       // IANA registry value: 11
-
-    // extensions defined in RFC 5054
-    final static ExtensionType EXT_SRP =
-            e(0x000C, "srp");                    // IANA registry value: 12
-
-    // extensions defined in RFC 5246
-    final static ExtensionType EXT_SIGNATURE_ALGORITHMS =
-            e(0x000D, "signature_algorithms");   // IANA registry value: 13
-
-    // extensions defined in RFC 5746
-    final static ExtensionType EXT_RENEGOTIATION_INFO =
-            e(0xff01, "renegotiation_info");     // IANA registry value: 65281
-}
-
-abstract class HelloExtension {
-
-    final ExtensionType type;
-
-    HelloExtension(ExtensionType type) {
-        this.type = type;
-    }
-
-    // Length of the encoded extension, including the type and length fields
-    abstract int length();
-
-    abstract void send(HandshakeOutStream s) throws IOException;
-
-    public abstract String toString();
-
-}
-
-final class UnknownExtension extends HelloExtension {
-
-    private final byte[] data;
-
-    UnknownExtension(HandshakeInStream s, int len, ExtensionType type)
-            throws IOException {
-        super(type);
-        data = new byte[len];
-        // s.read() does not handle 0-length arrays.
-        if (len != 0) {
-            s.read(data);
-        }
-    }
-
-    int length() {
-        return 4 + data.length;
-    }
-
-    void send(HandshakeOutStream s) throws IOException {
-        s.putInt16(type.id);
-        s.putBytes16(data);
-    }
-
-    public String toString() {
-        return "Unsupported extension " + type + ", data: " +
-            Debug.toString(data);
-    }
-}
-
-/*
- * [RFC4366] To facilitate secure connections to servers that host multiple
- * 'virtual' servers at a single underlying network address, clients MAY
- * include an extension of type "server_name" in the (extended) client hello.
- * The "extension_data" field of this extension SHALL contain "ServerNameList"
- * where:
- *
- *     struct {
- *         NameType name_type;
- *         select (name_type) {
- *             case host_name: HostName;
- *         } name;
- *     } ServerName;
- *
- *     enum {
- *         host_name(0), (255)
- *     } NameType;
- *
- *     opaque HostName<1..2^16-1>;
- *
- *     struct {
- *         ServerName server_name_list<1..2^16-1>
- *     } ServerNameList;
- */
-final class ServerNameExtension extends HelloExtension {
-
-    final static int NAME_HOST_NAME = 0;
-
-    private List<ServerName> names;
-    private int listLength;     // ServerNameList length
-
-    ServerNameExtension(List<String> hostnames) throws IOException {
-        super(ExtensionType.EXT_SERVER_NAME);
-
-        listLength = 0;
-        names = new ArrayList<ServerName>(hostnames.size());
-        for (String hostname : hostnames) {
-            if (hostname != null && hostname.length() != 0) {
-                // we only support DNS hostname now.
-                ServerName serverName =
-                        new ServerName(NAME_HOST_NAME, hostname);
-                names.add(serverName);
-                listLength += serverName.length;
-            }
-        }
-
-        // As we only support DNS hostname now, the hostname list must
-        // not contain more than one hostname
-        if (names.size() > 1) {
-            throw new SSLProtocolException(
-                    "The ServerNameList MUST NOT contain more than " +
-                    "one name of the same name_type");
-        }
-
-        // We only need to add "server_name" extension in ClientHello unless
-        // we support SNI in server side in the future. It is possible that
-        // the SNI is empty in ServerHello. As we don't support SNI in
-        // ServerHello now, we will throw exception for empty list for now.
-        if (listLength == 0) {
-            throw new SSLProtocolException(
-                    "The ServerNameList cannot be empty");
-        }
-    }
-
-    ServerNameExtension(HandshakeInStream s, int len)
-            throws IOException {
-        super(ExtensionType.EXT_SERVER_NAME);
-
-        int remains = len;
-        if (len >= 2) {    // "server_name" extension in ClientHello
-            listLength = s.getInt16();     // ServerNameList length
-            if (listLength == 0 || listLength + 2 != len) {
-                throw new SSLProtocolException(
-                        "Invalid " + type + " extension");
-            }
-
-            remains -= 2;
-            names = new ArrayList<ServerName>();
-            while (remains > 0) {
-                ServerName name = new ServerName(s);
-                names.add(name);
-                remains -= name.length;
-
-                // we may need to check the duplicated ServerName type
-            }
-        } else if (len == 0) {     // "server_name" extension in ServerHello
-            listLength = 0;
-            names = Collections.<ServerName>emptyList();
-        }
-
-        if (remains != 0) {
-            throw new SSLProtocolException("Invalid server_name extension");
-        }
-    }
-
-    static class ServerName {
-        final int length;
-        final int type;
-        final byte[] data;
-        final String hostname;
-
-        ServerName(int type, String hostname) throws IOException {
-            this.type = type;                       // NameType
-            this.hostname = hostname;
-            this.data = hostname.getBytes("UTF8");  // HostName
-            this.length = data.length + 3;          // NameType: 1 byte
-                                                    // HostName length: 2 bytes
-        }
-
-        ServerName(HandshakeInStream s) throws IOException {
-            type = s.getInt8();         // NameType
-            data = s.getBytes16();      // HostName (length read in getBytes16)
-            length = data.length + 3;   // NameType: 1 byte
-                                        // HostName length: 2 bytes
-            if (type == NAME_HOST_NAME) {
-                hostname = new String(data, "UTF8");
-            } else {
-                hostname = null;
-            }
-        }
-
-        public String toString() {
-            if (type == NAME_HOST_NAME) {
-                return "host_name: " + hostname;
-            } else {
-                return "unknown-" + type + ": " + Debug.toString(data);
-            }
-        }
-    }
-
-    int length() {
-        return listLength == 0 ? 4 : 6 + listLength;
-    }
-
-    void send(HandshakeOutStream s) throws IOException {
-        s.putInt16(type.id);
-        s.putInt16(listLength + 2);
-        if (listLength != 0) {
-            s.putInt16(listLength);
-
-            for (ServerName name : names) {
-                s.putInt8(name.type);           // NameType
-                s.putBytes16(name.data);        // HostName
-            }
-        }
-    }
-
-    public String toString() {
-        StringBuffer buffer = new StringBuffer();
-        for (ServerName name : names) {
-            buffer.append("[" + name + "]");
-        }
-
-        return "Extension " + type + ", server_name: " + buffer;
-    }
-}
-
-final class SupportedEllipticCurvesExtension extends HelloExtension {
-
-    // the extension value to send in the ClientHello message
-    static final SupportedEllipticCurvesExtension DEFAULT;
-
-    private static final boolean fips;
-
-    static {
-        int[] ids;
-        fips = SunJSSE.isFIPS();
-        if (fips == false) {
-            ids = new int[] {
-                // NIST curves first
-                // prefer NIST P-256, rest in order of increasing key length
-                23, 1, 3, 19, 21, 6, 7, 9, 10, 24, 11, 12, 25, 13, 14,
-                // non-NIST curves
-                15, 16, 17, 2, 18, 4, 5, 20, 8, 22,
-            };
-        } else {
-            ids = new int[] {
-                // same as above, but allow only NIST curves in FIPS mode
-                23, 1, 3, 19, 21, 6, 7, 9, 10, 24, 11, 12, 25, 13, 14,
-            };
-        }
-        DEFAULT = new SupportedEllipticCurvesExtension(ids);
-    }
-
-    private final int[] curveIds;
-
-    private SupportedEllipticCurvesExtension(int[] curveIds) {
-        super(ExtensionType.EXT_ELLIPTIC_CURVES);
-        this.curveIds = curveIds;
-    }
-
-    SupportedEllipticCurvesExtension(HandshakeInStream s, int len)
-            throws IOException {
-        super(ExtensionType.EXT_ELLIPTIC_CURVES);
-        int k = s.getInt16();
-        if (((len & 1) != 0) || (k + 2 != len)) {
-            throw new SSLProtocolException("Invalid " + type + " extension");
-        }
-        curveIds = new int[k >> 1];
-        for (int i = 0; i < curveIds.length; i++) {
-            curveIds[i] = s.getInt16();
-        }
-    }
-
-    boolean contains(int index) {
-        for (int curveId : curveIds) {
-            if (index == curveId) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    // Return a reference to the internal curveIds array.
-    // The caller must NOT modify the contents.
-    int[] curveIds() {
-        return curveIds;
-    }
-
-    int length() {
-        return 6 + (curveIds.length << 1);
-    }
-
-    void send(HandshakeOutStream s) throws IOException {
-        s.putInt16(type.id);
-        int k = curveIds.length << 1;
-        s.putInt16(k + 2);
-        s.putInt16(k);
-        for (int curveId : curveIds) {
-            s.putInt16(curveId);
-        }
-    }
-
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("Extension " + type + ", curve names: {");
-        boolean first = true;
-        for (int curveId : curveIds) {
-            if (first) {
-                first = false;
-            } else {
-                sb.append(", ");
-            }
-            // first check if it is a known named curve, then try other cases.
-            String oid = getCurveOid(curveId);
-            if (oid != null) {
-                ECParameterSpec spec = JsseJce.getECParameterSpec(oid);
-                // this toString() output will look nice for the current
-                // implementation of the ECParameterSpec class in the Sun
-                // provider, but may not look good for other implementations.
-                if (spec != null) {
-                    sb.append(spec.toString().split(" ")[0]);
-                } else {
-                    sb.append(oid);
-                }
-            } else if (curveId == ARBITRARY_PRIME) {
-                sb.append("arbitrary_explicit_prime_curves");
-            } else if (curveId == ARBITRARY_CHAR2) {
-                sb.append("arbitrary_explicit_char2_curves");
-            } else {
-                sb.append("unknown curve " + curveId);
-            }
-        }
-        sb.append("}");
-        return sb.toString();
-    }
-
-    // Test whether we support the curve with the given index.
-    static boolean isSupported(int index) {
-        if ((index <= 0) || (index >= NAMED_CURVE_OID_TABLE.length)) {
-            return false;
-        }
-        if (fips == false) {
-            // in non-FIPS mode, we support all valid indices
-            return true;
-        }
-        return DEFAULT.contains(index);
-    }
-
-    static int getCurveIndex(ECParameterSpec params) {
-        String oid = JsseJce.getNamedCurveOid(params);
-        if (oid == null) {
-            return -1;
-        }
-        Integer n = curveIndices.get(oid);
-        return (n == null) ? -1 : n;
-    }
-
-    static String getCurveOid(int index) {
-        if ((index > 0) && (index < NAMED_CURVE_OID_TABLE.length)) {
-            return NAMED_CURVE_OID_TABLE[index];
-        }
-        return null;
-    }
-
-    private final static int ARBITRARY_PRIME = 0xff01;
-    private final static int ARBITRARY_CHAR2 = 0xff02;
-
-    // See sun.security.ec.NamedCurve for the OIDs
-    private final static String[] NAMED_CURVE_OID_TABLE = new String[] {
-        null,                   //  (0) unused
-        "1.3.132.0.1",          //  (1) sect163k1, NIST K-163
-        "1.3.132.0.2",          //  (2) sect163r1
-        "1.3.132.0.15",         //  (3) sect163r2, NIST B-163
-        "1.3.132.0.24",         //  (4) sect193r1
-        "1.3.132.0.25",         //  (5) sect193r2
-        "1.3.132.0.26",         //  (6) sect233k1, NIST K-233
-        "1.3.132.0.27",         //  (7) sect233r1, NIST B-233
-        "1.3.132.0.3",          //  (8) sect239k1
-        "1.3.132.0.16",         //  (9) sect283k1, NIST K-283
-        "1.3.132.0.17",         // (10) sect283r1, NIST B-283
-        "1.3.132.0.36",         // (11) sect409k1, NIST K-409
-        "1.3.132.0.37",         // (12) sect409r1, NIST B-409
-        "1.3.132.0.38",         // (13) sect571k1, NIST K-571
-        "1.3.132.0.39",         // (14) sect571r1, NIST B-571
-        "1.3.132.0.9",          // (15) secp160k1
-        "1.3.132.0.8",          // (16) secp160r1
-        "1.3.132.0.30",         // (17) secp160r2
-        "1.3.132.0.31",         // (18) secp192k1
-        "1.2.840.10045.3.1.1",  // (19) secp192r1, NIST P-192
-        "1.3.132.0.32",         // (20) secp224k1
-        "1.3.132.0.33",         // (21) secp224r1, NIST P-224
-        "1.3.132.0.10",         // (22) secp256k1
-        "1.2.840.10045.3.1.7",  // (23) secp256r1, NIST P-256
-        "1.3.132.0.34",         // (24) secp384r1, NIST P-384
-        "1.3.132.0.35",         // (25) secp521r1, NIST P-521
-    };
-
-    private final static Map<String,Integer> curveIndices;
-
-    static {
-        curveIndices = new HashMap<String,Integer>();
-        for (int i = 1; i < NAMED_CURVE_OID_TABLE.length; i++) {
-            curveIndices.put(NAMED_CURVE_OID_TABLE[i], i);
-        }
-    }
-
-}
-
-final class SupportedEllipticPointFormatsExtension extends HelloExtension {
-
-    final static int FMT_UNCOMPRESSED = 0;
-    final static int FMT_ANSIX962_COMPRESSED_PRIME = 1;
-    final static int FMT_ANSIX962_COMPRESSED_CHAR2 = 2;
-
-    static final HelloExtension DEFAULT =
-        new SupportedEllipticPointFormatsExtension(
-            new byte[] {FMT_UNCOMPRESSED});
-
-    private final byte[] formats;
-
-    private SupportedEllipticPointFormatsExtension(byte[] formats) {
-        super(ExtensionType.EXT_EC_POINT_FORMATS);
-        this.formats = formats;
-    }
-
-    SupportedEllipticPointFormatsExtension(HandshakeInStream s, int len)
-            throws IOException {
-        super(ExtensionType.EXT_EC_POINT_FORMATS);
-        formats = s.getBytes8();
-        // RFC 4492 says uncompressed points must always be supported.
-        // Check just to make sure.
-        boolean uncompressed = false;
-        for (int format : formats) {
-            if (format == FMT_UNCOMPRESSED) {
-                uncompressed = true;
-                break;
-            }
-        }
-        if (uncompressed == false) {
-            throw new SSLProtocolException
-                ("Peer does not support uncompressed points");
-        }
-    }
-
-    int length() {
-        return 5 + formats.length;
-    }
-
-    void send(HandshakeOutStream s) throws IOException {
-        s.putInt16(type.id);
-        s.putInt16(formats.length + 1);
-        s.putBytes8(formats);
-    }
-
-    private static String toString(byte format) {
-        int f = format & 0xff;
-        switch (f) {
-        case FMT_UNCOMPRESSED:
-            return "uncompressed";
-        case FMT_ANSIX962_COMPRESSED_PRIME:
-            return "ansiX962_compressed_prime";
-        case FMT_ANSIX962_COMPRESSED_CHAR2:
-            return "ansiX962_compressed_char2";
-        default:
-            return "unknown-" + f;
-        }
-    }
-
-    public String toString() {
-        List<String> list = new ArrayList<>();
-        for (byte format : formats) {
-            list.add(toString(format));
-        }
-        return "Extension " + type + ", formats: " + list;
-    }
-}
-
-/*
- * For secure renegotiation, RFC5746 defines a new TLS extension,
- * "renegotiation_info" (with extension type 0xff01), which contains a
- * cryptographic binding to the enclosing TLS connection (if any) for
- * which the renegotiation is being performed.  The "extension data"
- * field of this extension contains a "RenegotiationInfo" structure:
- *
- *      struct {
- *          opaque renegotiated_connection<0..255>;
- *      } RenegotiationInfo;
- */
-final class RenegotiationInfoExtension extends HelloExtension {
-    private final byte[] renegotiated_connection;
-
-    RenegotiationInfoExtension(byte[] clientVerifyData,
-                byte[] serverVerifyData) {
-        super(ExtensionType.EXT_RENEGOTIATION_INFO);
-
-        if (clientVerifyData.length != 0) {
-            renegotiated_connection =
-                    new byte[clientVerifyData.length + serverVerifyData.length];
-            System.arraycopy(clientVerifyData, 0, renegotiated_connection,
-                    0, clientVerifyData.length);
-
-            if (serverVerifyData.length != 0) {
-                System.arraycopy(serverVerifyData, 0, renegotiated_connection,
-                        clientVerifyData.length, serverVerifyData.length);
-            }
-        } else {
-            // ignore both the client and server verify data.
-            renegotiated_connection = new byte[0];
-        }
-    }
-
-    RenegotiationInfoExtension(HandshakeInStream s, int len)
-                throws IOException {
-        super(ExtensionType.EXT_RENEGOTIATION_INFO);
-
-        // check the extension length
-        if (len < 1) {
-            throw new SSLProtocolException("Invalid " + type + " extension");
-        }
-
-        int renegoInfoDataLen = s.getInt8();
-        if (renegoInfoDataLen + 1 != len) {  // + 1 = the byte we just read
-            throw new SSLProtocolException("Invalid " + type + " extension");
-        }
-
-        renegotiated_connection = new byte[renegoInfoDataLen];
-        if (renegoInfoDataLen != 0) {
-            s.read(renegotiated_connection, 0, renegoInfoDataLen);
-        }
-    }
-
-
-    // Length of the encoded extension, including the type and length fields
-    int length() {
-        return 5 + renegotiated_connection.length;
-    }
-
-    void send(HandshakeOutStream s) throws IOException {
-        s.putInt16(type.id);
-        s.putInt16(renegotiated_connection.length + 1);
-        s.putBytes8(renegotiated_connection);
-    }
-
-    boolean isEmpty() {
-        return renegotiated_connection.length == 0;
-    }
-
-    byte[] getRenegotiatedConnection() {
-        return renegotiated_connection;
-    }
-
-    public String toString() {
-        return "Extension " + type + ", renegotiated_connection: " +
-                    (renegotiated_connection.length == 0 ? "<empty>" :
-                    Debug.toString(renegotiated_connection));
-    }
-
-}
-
-/*
- * [RFC5246] The client uses the "signature_algorithms" extension to
- * indicate to the server which signature/hash algorithm pairs may be
- * used in digital signatures.  The "extension_data" field of this
- * extension contains a "supported_signature_algorithms" value.
- *
- *     enum {
- *         none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
- *         sha512(6), (255)
- *     } HashAlgorithm;
- *
- *     enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
- *       SignatureAlgorithm;
- *
- *     struct {
- *           HashAlgorithm hash;
- *           SignatureAlgorithm signature;
- *     } SignatureAndHashAlgorithm;
- *
- *     SignatureAndHashAlgorithm
- *       supported_signature_algorithms<2..2^16-2>;
- */
-final class SignatureAlgorithmsExtension extends HelloExtension {
-
-    private Collection<SignatureAndHashAlgorithm> algorithms;
-    private int algorithmsLen;  // length of supported_signature_algorithms
-
-    SignatureAlgorithmsExtension(
-            Collection<SignatureAndHashAlgorithm> signAlgs) {
-
-        super(ExtensionType.EXT_SIGNATURE_ALGORITHMS);
-
-        algorithms = new ArrayList<SignatureAndHashAlgorithm>(signAlgs);
-        algorithmsLen =
-            SignatureAndHashAlgorithm.sizeInRecord() * algorithms.size();
-    }
-
-    SignatureAlgorithmsExtension(HandshakeInStream s, int len)
-                throws IOException {
-        super(ExtensionType.EXT_SIGNATURE_ALGORITHMS);
-
-        algorithmsLen = s.getInt16();
-        if (algorithmsLen == 0 || algorithmsLen + 2 != len) {
-            throw new SSLProtocolException("Invalid " + type + " extension");
-        }
-
-        algorithms = new ArrayList<SignatureAndHashAlgorithm>();
-        int remains = algorithmsLen;
-        int sequence = 0;
-        while (remains > 1) {   // needs at least two bytes
-            int hash = s.getInt8();         // hash algorithm
-            int signature = s.getInt8();    // signature algorithm
-
-            SignatureAndHashAlgorithm algorithm =
-                SignatureAndHashAlgorithm.valueOf(hash, signature, ++sequence);
-            algorithms.add(algorithm);
-            remains -= 2;  // one byte for hash, one byte for signature
-        }
-
-        if (remains != 0) {
-            throw new SSLProtocolException("Invalid server_name extension");
-        }
-    }
-
-    Collection<SignatureAndHashAlgorithm> getSignAlgorithms() {
-        return algorithms;
-    }
-
-    @Override
-    int length() {
-        return 6 + algorithmsLen;
-    }
-
-    @Override
-    void send(HandshakeOutStream s) throws IOException {
-        s.putInt16(type.id);
-        s.putInt16(algorithmsLen + 2);
-        s.putInt16(algorithmsLen);
-
-        for (SignatureAndHashAlgorithm algorithm : algorithms) {
-            s.putInt8(algorithm.getHashValue());      // HashAlgorithm
-            s.putInt8(algorithm.getSignatureValue()); // SignatureAlgorithm
-        }
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer buffer = new StringBuffer();
-        boolean opened = false;
-        for (SignatureAndHashAlgorithm signAlg : algorithms) {
-            if (opened) {
-                buffer.append(", " + signAlg.getAlgorithmName());
-            } else {
-                buffer.append(signAlg.getAlgorithmName());
-                opened = true;
-            }
-        }
-
-        return "Extension " + type + ", signature_algorithms: " + buffer;
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/InputRecord.java b/ojluni/src/main/java/sun/security/ssl/InputRecord.java
deleted file mode 100755
index f714488..0000000
--- a/ojluni/src/main/java/sun/security/ssl/InputRecord.java
+++ /dev/null
@@ -1,833 +0,0 @@
-/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.nio.*;
-import java.net.SocketException;
-import java.net.SocketTimeoutException;
-
-import javax.crypto.BadPaddingException;
-
-import javax.net.ssl.*;
-
-import sun.misc.HexDumpEncoder;
-
-
-/**
- * SSL 3.0 records, as pulled off a TCP stream.  Input records are
- * basically buffers tied to a particular input stream ... a layer
- * above this must map these records into the model of a continuous
- * stream of data.
- *
- * Since this returns SSL 3.0 records, it's the layer that needs to
- * map SSL 2.0 style handshake records into SSL 3.0 ones for those
- * "old" clients that interop with both V2 and V3 servers.  Not as
- * pretty as might be desired.
- *
- * NOTE:  During handshaking, each message must be hashed to support
- * verification that the handshake process wasn't compromised.
- *
- * @author David Brownell
- */
-class InputRecord extends ByteArrayInputStream implements Record {
-
-    private HandshakeHash       handshakeHash;
-    private int                 lastHashed;
-    boolean                     formatVerified = true;  // SSLv2 ruled out?
-    private boolean             isClosed;
-    private boolean             appDataValid;
-
-    // The ClientHello version to accept. If set to ProtocolVersion.SSL20Hello
-    // and the first message we read is a ClientHello in V2 format, we convert
-    // it to V3. Otherwise we throw an exception when encountering a V2 hello.
-    private ProtocolVersion     helloVersion;
-
-    /* Class and subclass dynamic debugging support */
-    static final Debug debug = Debug.getInstance("ssl");
-
-    /* The existing record length */
-    private int exlen;
-
-    /* V2 handshake message */
-    private byte v2Buf[];
-
-    /*
-     * Construct the record to hold the maximum sized input record.
-     * Data will be filled in separately.
-     */
-    InputRecord() {
-        super(new byte[maxRecordSize]);
-        setHelloVersion(ProtocolVersion.DEFAULT_HELLO);
-        pos = headerSize;
-        count = headerSize;
-        lastHashed = count;
-        exlen = 0;
-        v2Buf = null;
-    }
-
-    void setHelloVersion(ProtocolVersion helloVersion) {
-        this.helloVersion = helloVersion;
-    }
-
-    ProtocolVersion getHelloVersion() {
-        return helloVersion;
-    }
-
-    /*
-     * Enable format checks if initial handshaking hasn't completed
-     */
-    void enableFormatChecks() {
-        formatVerified = false;
-    }
-
-    // return whether the data in this record is valid, decrypted data
-    boolean isAppDataValid() {
-        return appDataValid;
-    }
-
-    void setAppDataValid(boolean value) {
-        appDataValid = value;
-    }
-
-    /*
-     * Return the content type of the record.
-     */
-    byte contentType() {
-        return buf[0];
-    }
-
-    /*
-     * For handshaking, we need to be able to hash every byte above the
-     * record marking layer.  This is where we're guaranteed to see those
-     * bytes, so this is where we can hash them ... especially in the
-     * case of hashing the initial V2 message!
-     */
-    void setHandshakeHash(HandshakeHash handshakeHash) {
-        this.handshakeHash = handshakeHash;
-    }
-
-    HandshakeHash getHandshakeHash() {
-        return handshakeHash;
-    }
-
-    void decrypt(MAC signer, CipherBox box) throws BadPaddingException {
-
-        BadPaddingException reservedBPE = null;
-        int tagLen = signer.MAClen();
-        int cipheredLength = count - headerSize;
-
-        if (!box.isNullCipher()) {
-            // sanity check length of the ciphertext
-            if (!box.sanityCheck(tagLen, cipheredLength)) {
-                throw new BadPaddingException(
-                    "ciphertext sanity check failed");
-            }
-
-            try {
-                // Note that the CipherBox.decrypt() does not change
-                // the capacity of the buffer.
-                count = headerSize +
-                        box.decrypt(buf, headerSize, cipheredLength, tagLen);
-            } catch (BadPaddingException bpe) {
-                // RFC 2246 states that decryption_failed should be used
-                // for this purpose. However, that allows certain attacks,
-                // so we just send bad record MAC. We also need to make
-                // sure to always check the MAC to avoid a timing attack
-                // for the same issue. See paper by Vaudenay et al and the
-                // update in RFC 4346/5246.
-                //
-                // Failover to message authentication code checking.
-                reservedBPE = bpe;
-            }
-        }
-
-        if (tagLen != 0) {
-            int macOffset = count - tagLen;
-            int contentLen = macOffset - headerSize;
-
-            // Note that although it is not necessary, we run the same MAC
-            // computation and comparison on the payload for both stream
-            // cipher and CBC block cipher.
-            if (contentLen < 0) {
-                // negative data length, something is wrong
-                if (reservedBPE == null) {
-                    reservedBPE = new BadPaddingException("bad record");
-                }
-
-                // set offset of the dummy MAC
-                macOffset = headerSize + cipheredLength - tagLen;
-                contentLen = macOffset - headerSize;
-            }
-
-            count -= tagLen;  // Set the count before any MAC checking
-                              // exception occurs, so that the following
-                              // process can read the actual decrypted
-                              // content (minus the MAC) in the fragment
-                              // if necessary.
-
-            // Run MAC computation and comparison on the payload.
-            if (checkMacTags(contentType(),
-                    buf, headerSize, contentLen, signer, false)) {
-                if (reservedBPE == null) {
-                    reservedBPE = new BadPaddingException("bad record MAC");
-                }
-            }
-
-            // Run MAC computation and comparison on the remainder.
-            //
-            // It is only necessary for CBC block cipher.  It is used to get a
-            // constant time of MAC computation and comparison on each record.
-            if (box.isCBCMode()) {
-                int remainingLen = calculateRemainingLen(
-                                        signer, cipheredLength, contentLen);
-
-                // NOTE: remainingLen may be bigger (less than 1 block of the
-                // hash algorithm of the MAC) than the cipheredLength. However,
-                // We won't need to worry about it because we always use a
-                // maximum buffer for every record.  We need a change here if
-                // we use small buffer size in the future.
-                if (remainingLen > buf.length) {
-                    // unlikely to happen, just a placehold
-                    throw new RuntimeException(
-                        "Internal buffer capacity error");
-                }
-
-                // Won't need to worry about the result on the remainder. And
-                // then we won't need to worry about what's actual data to
-                // check MAC tag on.  We start the check from the header of the
-                // buffer so that we don't need to construct a new byte buffer.
-                checkMacTags(contentType(), buf, 0, remainingLen, signer, true);
-            }
-        }
-
-        // Is it a failover?
-        if (reservedBPE != null) {
-            throw reservedBPE;
-        }
-    }
-
-    /*
-     * Run MAC computation and comparison
-     *
-     * Please DON'T change the content of the byte buffer parameter!
-     */
-    static boolean checkMacTags(byte contentType, byte[] buffer,
-            int offset, int contentLen, MAC signer, boolean isSimulated) {
-
-        int tagLen = signer.MAClen();
-        byte[] hash = signer.compute(
-                contentType, buffer, offset, contentLen, isSimulated);
-        if (hash == null || tagLen != hash.length) {
-            // Something is wrong with MAC implementation.
-            throw new RuntimeException("Internal MAC error");
-        }
-
-        int[] results = compareMacTags(buffer, offset + contentLen, hash);
-        return (results[0] != 0);
-    }
-
-    /*
-     * A constant-time comparison of the MAC tags.
-     *
-     * Please DON'T change the content of the byte buffer parameter!
-     */
-    private static int[] compareMacTags(
-            byte[] buffer, int offset, byte[] tag) {
-
-        // An array of hits is used to prevent Hotspot optimization for
-        // the purpose of a constant-time check.
-        int[] results = {0, 0};    // {missed #, matched #}
-
-        // The caller ensures there are enough bytes available in the buffer.
-        // So we won't need to check the length of the buffer.
-        for (int i = 0; i < tag.length; i++) {
-            if (buffer[offset + i] != tag[i]) {
-                results[0]++;       // mismatched bytes
-            } else {
-                results[1]++;       // matched bytes
-            }
-        }
-
-        return results;
-    }
-
-    /*
-     * Calculate the length of a dummy buffer to run MAC computation
-     * and comparison on the remainder.
-     *
-     * The caller MUST ensure that the fullLen is not less than usedLen.
-     */
-    static int calculateRemainingLen(
-            MAC signer, int fullLen, int usedLen) {
-
-        int blockLen = signer.hashBlockLen();
-        int minimalPaddingLen = signer.minimalPaddingLen();
-
-        // (blockLen - minimalPaddingLen) is the maximum message size of
-        // the last block of hash function operation. See FIPS 180-4, or
-        // MD5 specification.
-        fullLen += 13 - (blockLen - minimalPaddingLen);
-        usedLen += 13 - (blockLen - minimalPaddingLen);
-
-        // Note: fullLen is always not less than usedLen, and blockLen
-        // is always bigger than minimalPaddingLen, so we don't worry
-        // about negative values. 0x01 is added to the result to ensure
-        // that the return value is positive.  The extra one byte does
-        // not impact the overall MAC compression function evaluations.
-        return 0x01 + (int)(Math.ceil(fullLen/(1.0d * blockLen)) -
-                Math.ceil(usedLen/(1.0d * blockLen))) * signer.hashBlockLen();
-    }
-
-    /*
-     * Well ... hello_request messages are _never_ hashed since we can't
-     * know when they'd appear in the sequence.
-     */
-    void ignore(int bytes) {
-        if (bytes > 0) {
-            pos += bytes;
-            lastHashed = pos;
-        }
-    }
-
-    /*
-     * We hash the (plaintext) we've processed, but only on demand.
-     *
-     * There is one place where we want to access the hash in the middle
-     * of a record:  client cert message gets hashed, and part of the
-     * same record is the client cert verify message which uses that hash.
-     * So we track how much we've read and hashed.
-     */
-    void doHashes() {
-        int len = pos - lastHashed;
-
-        if (len > 0) {
-            hashInternal(buf, lastHashed, len);
-            lastHashed = pos;
-        }
-    }
-
-    /*
-     * Need a helper function so we can hash the V2 hello correctly
-     */
-    private void hashInternal(byte databuf [], int offset, int len) {
-        if (debug != null && Debug.isOn("data")) {
-            try {
-                HexDumpEncoder hd = new HexDumpEncoder();
-
-                System.out.println("[read] MD5 and SHA1 hashes:  len = "
-                    + len);
-                hd.encodeBuffer(new ByteArrayInputStream(databuf, offset, len),
-                    System.out);
-            } catch (IOException e) { }
-        }
-        handshakeHash.update(databuf, offset, len);
-    }
-
-
-    /*
-     * Handshake messages may cross record boundaries.  We "queue"
-     * these in big buffers if we need to cope with this problem.
-     * This is not anticipated to be a common case; if this turns
-     * out to be wrong, this can readily be sped up.
-     */
-    void queueHandshake(InputRecord r) throws IOException {
-        int len;
-
-        /*
-         * Hash any data that's read but unhashed.
-         */
-        doHashes();
-
-        /*
-         * Move any unread data to the front of the buffer,
-         * flagging it all as unhashed.
-         */
-        if (pos > headerSize) {
-            len = count - pos;
-            if (len != 0) {
-                System.arraycopy(buf, pos, buf, headerSize, len);
-            }
-            pos = headerSize;
-            lastHashed = pos;
-            count = headerSize + len;
-        }
-
-        /*
-         * Grow "buf" if needed
-         */
-        len = r.available() + count;
-        if (buf.length < len) {
-            byte        newbuf [];
-
-            newbuf = new byte [len];
-            System.arraycopy(buf, 0, newbuf, 0, count);
-            buf = newbuf;
-        }
-
-        /*
-         * Append the new buffer to this one.
-         */
-        System.arraycopy(r.buf, r.pos, buf, count, len - count);
-        count = len;
-
-        /*
-         * Adjust lastHashed; important for now with clients which
-         * send SSL V2 client hellos.  This will go away eventually,
-         * by buffer code cleanup.
-         */
-        len = r.lastHashed - r.pos;
-        if (pos == headerSize) {
-            lastHashed += len;
-        } else {
-            throw new SSLProtocolException("?? confused buffer hashing ??");
-        }
-        // we've read the record, advance the pointers
-        r.pos = r.count;
-    }
-
-
-    /**
-     * Prevent any more data from being read into this record,
-     * and flag the record as holding no data.
-     */
-    public void close() {
-        appDataValid = false;
-        isClosed = true;
-        mark = 0;
-        pos = 0;
-        count = 0;
-    }
-
-
-    /*
-     * We may need to send this SSL v2 "No Cipher" message back, if we
-     * are faced with an SSLv2 "hello" that's not saying "I talk v3".
-     * It's the only one documented in the V2 spec as a fatal error.
-     */
-    private static final byte[] v2NoCipher = {
-        (byte)0x80, (byte)0x03, // unpadded 3 byte record
-        (byte)0x00,             // ... error message
-        (byte)0x00, (byte)0x01  // ... NO_CIPHER error
-    };
-
-    private int readFully(InputStream s, byte b[], int off, int len)
-            throws IOException {
-        int n = 0;
-        while (n < len) {
-            int readLen = s.read(b, off + n, len - n);
-            if (readLen < 0) {
-                return readLen;
-            }
-
-            if (debug != null && Debug.isOn("packet")) {
-                try {
-                    HexDumpEncoder hd = new HexDumpEncoder();
-                    ByteBuffer bb = ByteBuffer.wrap(b, off + n, readLen);
-
-                    System.out.println("[Raw read]: length = " +
-                        bb.remaining());
-                    hd.encodeBuffer(bb, System.out);
-                } catch (IOException e) { }
-            }
-
-            n += readLen;
-            exlen += readLen;
-        }
-
-        return n;
-    }
-
-    /*
-     * Read the SSL V3 record ... first time around, check to see if it
-     * really IS a V3 record.  Handle SSL V2 clients which can talk V3.0,
-     * as well as real V3 record format; otherwise report an error.
-     */
-    void read(InputStream s, OutputStream o) throws IOException {
-        if (isClosed) {
-            return;
-        }
-
-        /*
-         * For SSL it really _is_ an error if the other end went away
-         * so ungracefully as to not shut down cleanly.
-         */
-        if(exlen < headerSize) {
-            int really = readFully(s, buf, exlen, headerSize - exlen);
-            if (really < 0) {
-                throw new EOFException("SSL peer shut down incorrectly");
-            }
-
-            pos = headerSize;
-            count = headerSize;
-            lastHashed = pos;
-        }
-
-        /*
-         * The first record might use some other record marking convention,
-         * typically SSL v2 header.  (PCT could also be detected here.)
-         * This case is currently common -- Navigator 3.0 usually works
-         * this way, as do IE 3.0 and other products.
-         */
-        if (!formatVerified) {
-            formatVerified = true;
-            /*
-             * The first record must either be a handshake record or an
-             * alert message. If it's not, it is either invalid or an
-             * SSLv2 message.
-             */
-            if (buf[0] != ct_handshake && buf[0] != ct_alert) {
-                handleUnknownRecord(s, o);
-            } else {
-                readV3Record(s, o);
-            }
-        } else { // formatVerified == true
-            readV3Record(s, o);
-        }
-    }
-
-    /**
-     * Read a SSL/TLS record. Throw an IOException if the format is invalid.
-     */
-    private void readV3Record(InputStream s, OutputStream o)
-            throws IOException {
-        ProtocolVersion recordVersion = ProtocolVersion.valueOf(buf[1], buf[2]);
-        // Check if too old (currently not possible)
-        // or if the major version does not match.
-        // The actual version negotiation is in the handshaker classes
-        if ((recordVersion.v < ProtocolVersion.MIN.v)
-                || (recordVersion.major > ProtocolVersion.MAX.major)) {
-            throw new SSLException(
-                "Unsupported record version " + recordVersion);
-        }
-
-        /*
-         * Get and check length, then the data.
-         */
-        int contentLen = ((buf[3] & 0x0ff) << 8) + (buf[4] & 0xff);
-
-        /*
-         * Check for upper bound.
-         */
-        if (contentLen < 0 || contentLen > maxLargeRecordSize - headerSize) {
-            throw new SSLProtocolException("Bad InputRecord size"
-                + ", count = " + contentLen
-                + ", buf.length = " + buf.length);
-        }
-
-        /*
-         * Grow "buf" if needed. Since buf is maxRecordSize by default,
-         * this only occurs when we receive records which violate the
-         * SSL specification. This is a workaround for a Microsoft SSL bug.
-         */
-        if (contentLen > buf.length - headerSize) {
-            byte[] newbuf = new byte[contentLen + headerSize];
-            System.arraycopy(buf, 0, newbuf, 0, headerSize);
-            buf = newbuf;
-        }
-
-        if (exlen < contentLen + headerSize) {
-            int really = readFully(
-                s, buf, exlen, contentLen + headerSize - exlen);
-            if (really < 0) {
-                throw new SSLException("SSL peer shut down incorrectly");
-            }
-        }
-
-        // now we've got a complete record.
-        count = contentLen + headerSize;
-        exlen = 0;
-
-        if (debug != null && Debug.isOn("record")) {
-            if (count < 0 || count > (maxRecordSize - headerSize)) {
-                System.out.println(Thread.currentThread().getName()
-                    + ", Bad InputRecord size" + ", count = " + count);
-            }
-            System.out.println(Thread.currentThread().getName()
-                + ", READ: " + recordVersion + " "
-                + contentName(contentType()) + ", length = " + available());
-        }
-        /*
-         * then caller decrypts, verifies, and uncompresses
-         */
-    }
-
-    /**
-     * Deal with unknown records. Called if the first data we read on this
-     * connection does not look like an SSL/TLS record. It could a SSLv2
-     * message, or just garbage.
-     */
-    private void handleUnknownRecord(InputStream s, OutputStream o)
-            throws IOException {
-        /*
-         * No?  Oh well; does it look like a V2 "ClientHello"?
-         * That'd be an unpadded handshake message; we don't
-         * bother checking length just now.
-         */
-        if (((buf[0] & 0x080) != 0) && buf[2] == 1) {
-            /*
-             * if the user has disabled SSLv2Hello (using
-             * setEnabledProtocol) then throw an
-             * exception
-             */
-            if (helloVersion != ProtocolVersion.SSL20Hello) {
-                throw new SSLHandshakeException("SSLv2Hello is disabled");
-            }
-
-            ProtocolVersion recordVersion =
-                                ProtocolVersion.valueOf(buf[3], buf[4]);
-
-            if (recordVersion == ProtocolVersion.SSL20Hello) {
-                /*
-                 * Looks like a V2 client hello, but not one saying
-                 * "let's talk SSLv3".  So we send an SSLv2 error
-                 * message, one that's treated as fatal by clients.
-                 * (Otherwise we'll hang.)
-                 */
-                try {
-                    writeBuffer(o, v2NoCipher, 0, v2NoCipher.length);
-                } catch (Exception e) {
-                    /* NOTHING */
-                }
-                throw new SSLException("Unsupported SSL v2.0 ClientHello");
-            }
-
-            /*
-             * If we can map this into a V3 ClientHello, read and
-             * hash the rest of the V2 handshake, turn it into a
-             * V3 ClientHello message, and pass it up.
-             */
-            int len = ((buf[0] & 0x7f) << 8) +
-                (buf[1] & 0xff) - 3;
-            if (v2Buf == null) {
-                v2Buf = new byte[len];
-            }
-            if (exlen < len + headerSize) {
-                int really = readFully(
-                        s, v2Buf, exlen - headerSize, len + headerSize - exlen);
-                if (really < 0) {
-                    throw new EOFException("SSL peer shut down incorrectly");
-                }
-            }
-
-            // now we've got a complete record.
-            exlen = 0;
-
-            hashInternal(buf, 2, 3);
-            hashInternal(v2Buf, 0, len);
-            V2toV3ClientHello(v2Buf);
-            v2Buf = null;
-            lastHashed = count;
-
-            if (debug != null && Debug.isOn("record"))  {
-                System.out.println(
-                    Thread.currentThread().getName()
-                    + ", READ:  SSL v2, contentType = "
-                    + contentName(contentType())
-                    + ", translated length = " + available());
-            }
-            return;
-
-        } else {
-            /*
-             * Does it look like a V2 "ServerHello"?
-             */
-            if (((buf [0] & 0x080) != 0) && buf [2] == 4) {
-                throw new SSLException(
-                    "SSL V2.0 servers are not supported.");
-            }
-
-            /*
-             * If this is a V2 NoCipher message then this means
-             * the other server doesn't support V3. Otherwise, we just
-             * don't understand what it's saying.
-             */
-            for (int i = 0; i < v2NoCipher.length; i++) {
-                if (buf[i] != v2NoCipher[i]) {
-                    throw new SSLException(
-                        "Unrecognized SSL message, plaintext connection?");
-                }
-            }
-
-            throw new SSLException("SSL V2.0 servers are not supported.");
-        }
-    }
-
-    /*
-     * Actually do the write here.  For SSLEngine's HS data,
-     * we'll override this method and let it take the appropriate
-     * action.
-     */
-    void writeBuffer(OutputStream s, byte [] buf, int off, int len)
-            throws IOException {
-        s.write(buf, 0, len);
-        s.flush();
-    }
-
-    /*
-     * Support "old" clients which are capable of SSL V3.0 protocol ... for
-     * example, Navigator 3.0 clients.  The V2 message is in the header and
-     * the bytes passed as parameter.  This routine translates the V2 message
-     * into an equivalent V3 one.
-     */
-    private void V2toV3ClientHello(byte v2Msg []) throws SSLException
-    {
-        int i;
-
-        /*
-         * Build the first part of the V3 record header from the V2 one
-         * that's now buffered up.  (Lengths are fixed up later).
-         */
-        buf [0] = ct_handshake;
-        buf [1] = buf [3];      // V3.x
-        buf[2] = buf[4];
-        // header [3..4] for handshake message length
-        // count = 5;
-
-        /*
-         * Store the generic V3 handshake header:  4 bytes
-         */
-        buf [5] = 1;    // HandshakeMessage.ht_client_hello
-        // buf [6..8] for length of ClientHello (int24)
-        // count += 4;
-
-        /*
-         * ClientHello header starts with SSL version
-         */
-        buf [9] = buf [1];
-        buf [10] = buf [2];
-        // count += 2;
-        count = 11;
-
-        /*
-         * Start parsing the V2 message ...
-         */
-        int      cipherSpecLen, sessionIdLen, nonceLen;
-
-        cipherSpecLen = ((v2Msg [0] & 0xff) << 8) + (v2Msg [1] & 0xff);
-        sessionIdLen  = ((v2Msg [2] & 0xff) << 8) + (v2Msg [3] & 0xff);
-        nonceLen   = ((v2Msg [4] & 0xff) << 8) + (v2Msg [5] & 0xff);
-
-        /*
-         * Copy Random value/nonce ... if less than the 32 bytes of
-         * a V3 "Random", right justify and zero pad to the left.  Else
-         * just take the last 32 bytes.
-         */
-        int      offset = 6 + cipherSpecLen + sessionIdLen;
-
-        if (nonceLen < 32) {
-            for (i = 0; i < (32 - nonceLen); i++)
-                buf [count++] = 0;
-            System.arraycopy(v2Msg, offset, buf, count, nonceLen);
-            count += nonceLen;
-        } else {
-            System.arraycopy(v2Msg, offset + (nonceLen - 32),
-                    buf, count, 32);
-            count += 32;
-        }
-
-        /*
-         * Copy Session ID (only one byte length!)
-         */
-        offset -= sessionIdLen;
-        buf [count++] = (byte) sessionIdLen;
-
-        System.arraycopy(v2Msg, offset, buf, count, sessionIdLen);
-        count += sessionIdLen;
-
-        /*
-         * Copy and translate cipher suites ... V2 specs with first byte zero
-         * are really V3 specs (in the last 2 bytes), just copy those and drop
-         * the other ones.  Preference order remains unchanged.
-         *
-         * Example:  Netscape Navigator 3.0 (exportable) says:
-         *
-         * 0/3,     SSL_RSA_EXPORT_WITH_RC4_40_MD5
-         * 0/6,     SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
-         *
-         * Microsoft Internet Explorer 3.0 (exportable) supports only
-         *
-         * 0/3,     SSL_RSA_EXPORT_WITH_RC4_40_MD5
-         */
-        int j;
-
-        offset -= cipherSpecLen;
-        j = count + 2;
-
-        for (i = 0; i < cipherSpecLen; i += 3) {
-            if (v2Msg [offset + i] != 0)
-                continue;
-            buf [j++] = v2Msg [offset + i + 1];
-            buf [j++] = v2Msg [offset + i + 2];
-        }
-
-        j -= count + 2;
-        buf [count++] = (byte) (j >>> 8);
-        buf [count++] = (byte) j;
-        count += j;
-
-        /*
-         * Append compression methods (default/null only)
-         */
-        buf [count++] = 1;
-        buf [count++] = 0;      // Session.compression_null
-
-        /*
-         * Fill in lengths of the messages we synthesized (nested:
-         * V3 handshake message within V3 record) and then return
-         */
-        buf [3] = (byte) (count - headerSize);
-        buf [4] = (byte) ((count - headerSize) >>> 8);
-
-        buf [headerSize + 1] = 0;
-        buf [headerSize + 2] = (byte) (((count - headerSize) - 4) >>> 8);
-        buf [headerSize + 3] = (byte) ((count - headerSize) - 4);
-
-        pos = headerSize;
-    }
-
-    /**
-     * Return a description for the given content type. This method should be
-     * in Record, but since that is an interface this is not possible.
-     * Called from InputRecord and OutputRecord.
-     */
-    static String contentName(int contentType) {
-        switch (contentType) {
-        case ct_change_cipher_spec:
-            return "Change Cipher Spec";
-        case ct_alert:
-            return "Alert";
-        case ct_handshake:
-            return "Handshake";
-        case ct_application_data:
-            return "Application Data";
-        default:
-            return "contentType = " + contentType;
-        }
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/JsseJce.java b/ojluni/src/main/java/sun/security/ssl/JsseJce.java
deleted file mode 100755
index d91b8f4..0000000
--- a/ojluni/src/main/java/sun/security/ssl/JsseJce.java
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.util.*;
-import java.math.BigInteger;
-
-import java.security.*;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.RSAPublicKeySpec;
-import java.security.spec.*;
-
-import javax.crypto.*;
-
-// explicit import to override the Provider class in this package
-import java.security.Provider;
-
-// need internal Sun classes for FIPS tricks
-import sun.security.jca.Providers;
-import sun.security.jca.ProviderList;
-
-import sun.security.ec.ECParameters;
-import sun.security.ec.NamedCurve;
-
-import static sun.security.ssl.SunJSSE.cryptoProvider;
-
-/**
- * This class contains a few static methods for interaction with the JCA/JCE
- * to obtain implementations, etc.
- *
- * @author  Andreas Sterbenz
- */
-final class JsseJce {
-
-    private final static Debug debug = Debug.getInstance("ssl");
-
-    private final static ProviderList fipsProviderList;
-
-    // Flag indicating whether EC crypto is available.
-    // If null, then we have not checked yet.
-    // If yes, then all the EC based crypto we need is available.
-    private static Boolean ecAvailable;
-
-    // Flag indicating whether Kerberos crypto is available.
-    // If true, then all the Kerberos-based crypto we need is available.
-    private final static boolean kerberosAvailable;
-    static {
-        boolean temp;
-        try {
-            AccessController.doPrivileged(
-                new PrivilegedExceptionAction<Void>() {
-                    public Void run() throws Exception {
-                        // Test for Kerberos using the bootstrap class loader
-                        Class.forName("sun.security.krb5.PrincipalName", true,
-                                null);
-                        return null;
-                    }
-                });
-            temp = true;
-
-        } catch (Exception e) {
-            temp = false;
-        }
-        kerberosAvailable = temp;
-    }
-
-    static {
-        // force FIPS flag initialization
-        // Because isFIPS() is synchronized and cryptoProvider is not modified
-        // after it completes, this also eliminates the need for any further
-        // synchronization when accessing cryptoProvider
-        if (SunJSSE.isFIPS() == false) {
-            fipsProviderList = null;
-        } else {
-            // Setup a ProviderList that can be used by the trust manager
-            // during certificate chain validation. All the crypto must be
-            // from the FIPS provider, but we also allow the required
-            // certificate related services from the SUN provider.
-            Provider sun = Security.getProvider("SUN");
-            if (sun == null) {
-                throw new RuntimeException
-                    ("FIPS mode: SUN provider must be installed");
-            }
-            Provider sunCerts = new SunCertificates(sun);
-            fipsProviderList = ProviderList.newList(cryptoProvider, sunCerts);
-        }
-    }
-
-    private static final class SunCertificates extends Provider {
-        SunCertificates(final Provider p) {
-            super("SunCertificates", 1.0d, "SunJSSE internal");
-            AccessController.doPrivileged(new PrivilegedAction<Object>() {
-                public Object run() {
-                    // copy certificate related services from the Sun provider
-                    for (Map.Entry<Object,Object> entry : p.entrySet()) {
-                        String key = (String)entry.getKey();
-                        if (key.startsWith("CertPathValidator.")
-                                || key.startsWith("CertPathBuilder.")
-                                || key.startsWith("CertStore.")
-                                || key.startsWith("CertificateFactory.")) {
-                            put(key, entry.getValue());
-                        }
-                    }
-                    return null;
-                }
-            });
-        }
-    }
-
-    /**
-     * JCE transformation string for RSA with PKCS#1 v1.5 padding.
-     * Can be used for encryption, decryption, signing, verifying.
-     */
-    final static String CIPHER_RSA_PKCS1 = "RSA/ECB/PKCS1Padding";
-    /**
-     * JCE transformation string for the stream cipher RC4.
-     */
-    final static String CIPHER_RC4 = "RC4";
-    /**
-     * JCE transformation string for DES in CBC mode without padding.
-     */
-    final static String CIPHER_DES = "DES/CBC/NoPadding";
-    /**
-     * JCE transformation string for (3-key) Triple DES in CBC mode
-     * without padding.
-     */
-    final static String CIPHER_3DES = "DESede/CBC/NoPadding";
-    /**
-     * JCE transformation string for AES in CBC mode
-     * without padding.
-     */
-    final static String CIPHER_AES = "AES/CBC/NoPadding";
-    /**
-     * JCA identifier string for DSA, i.e. a DSA with SHA-1.
-     */
-    final static String SIGNATURE_DSA = "DSA";
-    /**
-     * JCA identifier string for ECDSA, i.e. a ECDSA with SHA-1.
-     */
-    final static String SIGNATURE_ECDSA = "SHA1withECDSA";
-    /**
-     * JCA identifier string for Raw DSA, i.e. a DSA signature without
-     * hashing where the application provides the SHA-1 hash of the data.
-     * Note that the standard name is "NONEwithDSA" but we use "RawDSA"
-     * for compatibility.
-     */
-    final static String SIGNATURE_RAWDSA = "RawDSA";
-    /**
-     * JCA identifier string for Raw ECDSA, i.e. a DSA signature without
-     * hashing where the application provides the SHA-1 hash of the data.
-     */
-    final static String SIGNATURE_RAWECDSA = "NONEwithECDSA";
-    /**
-     * JCA identifier string for Raw RSA, i.e. a RSA PKCS#1 v1.5 signature
-     * without hashing where the application provides the hash of the data.
-     * Used for RSA client authentication with a 36 byte hash.
-     */
-    final static String SIGNATURE_RAWRSA = "NONEwithRSA";
-    /**
-     * JCA identifier string for the SSL/TLS style RSA Signature. I.e.
-     * an signature using RSA with PKCS#1 v1.5 padding signing a
-     * concatenation of an MD5 and SHA-1 digest.
-     */
-    final static String SIGNATURE_SSLRSA = "MD5andSHA1withRSA";
-
-    private JsseJce() {
-        // no instantiation of this class
-    }
-
-    synchronized static boolean isEcAvailable() {
-        if (ecAvailable == null) {
-            try {
-                JsseJce.getSignature(SIGNATURE_ECDSA);
-                JsseJce.getSignature(SIGNATURE_RAWECDSA);
-                JsseJce.getKeyAgreement("ECDH");
-                JsseJce.getKeyFactory("EC");
-                JsseJce.getKeyPairGenerator("EC");
-                ecAvailable = true;
-            } catch (Exception e) {
-                ecAvailable = false;
-            }
-        }
-        return ecAvailable;
-    }
-
-    synchronized static void clearEcAvailable() {
-        ecAvailable = null;
-    }
-
-    static boolean isKerberosAvailable() {
-        return kerberosAvailable;
-    }
-
-    /**
-     * Return an JCE cipher implementation for the specified algorithm.
-     */
-    static Cipher getCipher(String transformation)
-            throws NoSuchAlgorithmException {
-        try {
-            if (cryptoProvider == null) {
-                return Cipher.getInstance(transformation);
-            } else {
-                return Cipher.getInstance(transformation, cryptoProvider);
-            }
-        } catch (NoSuchPaddingException e) {
-            throw new NoSuchAlgorithmException(e);
-        }
-    }
-
-    /**
-     * Return an JCA signature implementation for the specified algorithm.
-     * The algorithm string should be one of the constants defined
-     * in this class.
-     */
-    static Signature getSignature(String algorithm)
-            throws NoSuchAlgorithmException {
-        if (cryptoProvider == null) {
-            return Signature.getInstance(algorithm);
-        } else {
-            // reference equality
-            if (algorithm == SIGNATURE_SSLRSA) {
-                // The SunPKCS11 provider currently does not support this
-                // special algorithm. We allow a fallback in this case because
-                // the SunJSSE implementation does the actual crypto using
-                // a NONEwithRSA signature obtained from the cryptoProvider.
-                if (cryptoProvider.getService("Signature", algorithm) == null) {
-                    // Calling Signature.getInstance() and catching the
-                    // exception would be cleaner, but exceptions are a little
-                    // expensive. So we check directly via getService().
-                    try {
-                        return Signature.getInstance(algorithm, "SunJSSE");
-                    } catch (NoSuchProviderException e) {
-                        throw new NoSuchAlgorithmException(e);
-                    }
-                }
-            }
-            return Signature.getInstance(algorithm, cryptoProvider);
-        }
-    }
-
-    static KeyGenerator getKeyGenerator(String algorithm)
-            throws NoSuchAlgorithmException {
-        if (cryptoProvider == null) {
-            return KeyGenerator.getInstance(algorithm);
-        } else {
-            return KeyGenerator.getInstance(algorithm, cryptoProvider);
-        }
-    }
-
-    static KeyPairGenerator getKeyPairGenerator(String algorithm)
-            throws NoSuchAlgorithmException {
-        if (cryptoProvider == null) {
-            return KeyPairGenerator.getInstance(algorithm);
-        } else {
-            return KeyPairGenerator.getInstance(algorithm, cryptoProvider);
-        }
-    }
-
-    static KeyAgreement getKeyAgreement(String algorithm)
-            throws NoSuchAlgorithmException {
-        if (cryptoProvider == null) {
-            return KeyAgreement.getInstance(algorithm);
-        } else {
-            return KeyAgreement.getInstance(algorithm, cryptoProvider);
-        }
-    }
-
-    static Mac getMac(String algorithm)
-            throws NoSuchAlgorithmException {
-        if (cryptoProvider == null) {
-            return Mac.getInstance(algorithm);
-        } else {
-            return Mac.getInstance(algorithm, cryptoProvider);
-        }
-    }
-
-    static KeyFactory getKeyFactory(String algorithm)
-            throws NoSuchAlgorithmException {
-        if (cryptoProvider == null) {
-            return KeyFactory.getInstance(algorithm);
-        } else {
-            return KeyFactory.getInstance(algorithm, cryptoProvider);
-        }
-    }
-
-    static SecureRandom getSecureRandom() throws KeyManagementException {
-        if (cryptoProvider == null) {
-            return new SecureRandom();
-        }
-        // Try "PKCS11" first. If that is not supported, iterate through
-        // the provider and return the first working implementation.
-        try {
-            return SecureRandom.getInstance("PKCS11", cryptoProvider);
-        } catch (NoSuchAlgorithmException e) {
-            // ignore
-        }
-        for (Provider.Service s : cryptoProvider.getServices()) {
-            if (s.getType().equals("SecureRandom")) {
-                try {
-                    return SecureRandom.getInstance(s.getAlgorithm(), cryptoProvider);
-                } catch (NoSuchAlgorithmException ee) {
-                    // ignore
-                }
-            }
-        }
-        throw new KeyManagementException("FIPS mode: no SecureRandom "
-            + " implementation found in provider " + cryptoProvider.getName());
-    }
-
-    static MessageDigest getMD5() {
-        return getMessageDigest("MD5");
-    }
-
-    static MessageDigest getSHA() {
-        return getMessageDigest("SHA");
-    }
-
-    static MessageDigest getMessageDigest(String algorithm) {
-        try {
-            if (cryptoProvider == null) {
-                return MessageDigest.getInstance(algorithm);
-            } else {
-                return MessageDigest.getInstance(algorithm, cryptoProvider);
-            }
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException
-                        ("Algorithm " + algorithm + " not available", e);
-        }
-    }
-
-    static int getRSAKeyLength(PublicKey key) {
-        BigInteger modulus;
-        if (key instanceof RSAPublicKey) {
-            modulus = ((RSAPublicKey)key).getModulus();
-        } else {
-            RSAPublicKeySpec spec = getRSAPublicKeySpec(key);
-            modulus = spec.getModulus();
-        }
-        return modulus.bitLength();
-    }
-
-    static RSAPublicKeySpec getRSAPublicKeySpec(PublicKey key) {
-        if (key instanceof RSAPublicKey) {
-            RSAPublicKey rsaKey = (RSAPublicKey)key;
-            return new RSAPublicKeySpec(rsaKey.getModulus(),
-                                        rsaKey.getPublicExponent());
-        }
-        try {
-            KeyFactory factory = JsseJce.getKeyFactory("RSA");
-            return factory.getKeySpec(key, RSAPublicKeySpec.class);
-        } catch (Exception e) {
-            throw (RuntimeException)new RuntimeException().initCause(e);
-        }
-    }
-
-    static ECParameterSpec getECParameterSpec(String namedCurveOid) {
-        return NamedCurve.getECParameterSpec(namedCurveOid);
-    }
-
-    static String getNamedCurveOid(ECParameterSpec params) {
-        return ECParameters.getCurveName(params);
-    }
-
-    static ECPoint decodePoint(byte[] encoded, EllipticCurve curve)
-            throws java.io.IOException {
-        return ECParameters.decodePoint(encoded, curve);
-    }
-
-    static byte[] encodePoint(ECPoint point, EllipticCurve curve) {
-        return ECParameters.encodePoint(point, curve);
-    }
-
-    // In FIPS mode, set thread local providers; otherwise a no-op.
-    // Must be paired with endFipsProvider.
-    static Object beginFipsProvider() {
-        if (fipsProviderList == null) {
-            return null;
-        } else {
-            return Providers.beginThreadProviderList(fipsProviderList);
-        }
-    }
-
-    static void endFipsProvider(Object o) {
-        if (fipsProviderList != null) {
-            Providers.endThreadProviderList((ProviderList)o);
-        }
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/KerberosClientKeyExchange.java b/ojluni/src/main/java/sun/security/ssl/KerberosClientKeyExchange.java
deleted file mode 100755
index 339f94b..0000000
--- a/ojluni/src/main/java/sun/security/ssl/KerberosClientKeyExchange.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.security.AccessController;
-import java.security.AccessControlContext;
-import java.security.Principal;
-import java.security.PrivilegedAction;
-import java.security.SecureRandom;
-import javax.crypto.SecretKey;
-
-/**
- * A helper class that calls the KerberosClientKeyExchange implementation.
- */
-public class KerberosClientKeyExchange extends HandshakeMessage {
-
-    private static final String IMPL_CLASS =
-        "sun.security.ssl.krb5.KerberosClientKeyExchangeImpl";
-
-    private static final Class<?> implClass = AccessController.doPrivileged(
-            new PrivilegedAction<Class<?>>() {
-                public Class<?> run() {
-                    try {
-                        return Class.forName(IMPL_CLASS, true, null);
-                    } catch (ClassNotFoundException cnf) {
-                        return null;
-                    }
-                }
-            }
-        );
-    private final KerberosClientKeyExchange impl = createImpl();
-
-    private KerberosClientKeyExchange createImpl() {
-        if (getClass() == KerberosClientKeyExchange.class) {
-            try {
-                return (KerberosClientKeyExchange)implClass.newInstance();
-            } catch (InstantiationException e) {
-                throw new AssertionError(e);
-            } catch (IllegalAccessException e) {
-                throw new AssertionError(e);
-            }
-        }
-        return null;
-    }
-
-    public KerberosClientKeyExchange() {
-        // empty
-    }
-
-    public KerberosClientKeyExchange(String serverName, boolean isLoopback,
-        AccessControlContext acc, ProtocolVersion protocolVersion,
-        SecureRandom rand) throws IOException {
-
-        if (impl != null) {
-            init(serverName, isLoopback, acc, protocolVersion, rand);
-        } else {
-            throw new IllegalStateException("Kerberos is unavailable");
-        }
-    }
-
-    public KerberosClientKeyExchange(ProtocolVersion protocolVersion,
-        ProtocolVersion clientVersion, SecureRandom rand,
-        HandshakeInStream input, SecretKey[] serverKeys) throws IOException {
-
-        if (impl != null) {
-            init(protocolVersion, clientVersion, rand, input, serverKeys);
-        } else {
-            throw new IllegalStateException("Kerberos is unavailable");
-        }
-    }
-
-    @Override
-    int messageType() {
-        return ht_client_key_exchange;
-    }
-
-    @Override
-    public int  messageLength() {
-        return impl.messageLength();
-    }
-
-    @Override
-    public void send(HandshakeOutStream s) throws IOException {
-        impl.send(s);
-    }
-
-    @Override
-    public void print(PrintStream p) throws IOException {
-        impl.print(p);
-    }
-
-    public void init(String serverName, boolean isLoopback,
-        AccessControlContext acc, ProtocolVersion protocolVersion,
-        SecureRandom rand) throws IOException {
-
-        if (impl != null) {
-            impl.init(serverName, isLoopback, acc, protocolVersion, rand);
-        }
-    }
-
-    public void init(ProtocolVersion protocolVersion,
-        ProtocolVersion clientVersion, SecureRandom rand,
-        HandshakeInStream input, SecretKey[] serverKeys) throws IOException {
-
-        if (impl != null) {
-            impl.init(protocolVersion, clientVersion, rand, input, serverKeys);
-        }
-    }
-
-    public byte[] getUnencryptedPreMasterSecret() {
-        return impl.getUnencryptedPreMasterSecret();
-    }
-
-    public Principal getPeerPrincipal(){
-        return impl.getPeerPrincipal();
-    }
-
-    public Principal getLocalPrincipal(){
-        return impl.getLocalPrincipal();
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/Krb5Helper.java b/ojluni/src/main/java/sun/security/ssl/Krb5Helper.java
deleted file mode 100755
index d1bbe83..0000000
--- a/ojluni/src/main/java/sun/security/ssl/Krb5Helper.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.Permission;
-import java.security.Principal;
-import java.security.PrivilegedAction;
-import javax.crypto.SecretKey;
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginException;
-
-/**
- * A helper class for Kerberos APIs.
- */
-public final class Krb5Helper {
-
-    private Krb5Helper() { }
-
-    // loads Krb5Proxy implementation class if available
-    private static final String IMPL_CLASS =
-        "sun.security.ssl.krb5.Krb5ProxyImpl";
-
-    private static final Krb5Proxy proxy =
-        AccessController.doPrivileged(new PrivilegedAction<Krb5Proxy>() {
-            public Krb5Proxy run() {
-                try {
-                    Class<?> c = Class.forName(IMPL_CLASS, true, null);
-                    return (Krb5Proxy)c.newInstance();
-                } catch (ClassNotFoundException cnf) {
-                    return null;
-                } catch (InstantiationException e) {
-                    throw new AssertionError(e);
-                } catch (IllegalAccessException e) {
-                    throw new AssertionError(e);
-                }
-            }});
-
-    /**
-     * Returns true if Kerberos is available.
-     */
-    public static boolean isAvailable() {
-        return proxy != null;
-    }
-
-    private static void ensureAvailable() {
-        if (proxy == null)
-            throw new AssertionError("Kerberos should have been available");
-    }
-
-    /**
-     * Returns the Subject associated with client-side of the SSL socket.
-     */
-    public static Subject getClientSubject(AccessControlContext acc)
-            throws LoginException {
-        ensureAvailable();
-        return proxy.getClientSubject(acc);
-    }
-
-    /**
-     * Returns the Subject associated with server-side of the SSL socket.
-     */
-    public static Subject getServerSubject(AccessControlContext acc)
-            throws LoginException {
-        ensureAvailable();
-        return proxy.getServerSubject(acc);
-    }
-
-    /**
-     * Returns the KerberosKeys for the default server-side principal.
-     */
-    public static SecretKey[] getServerKeys(AccessControlContext acc)
-            throws LoginException {
-        ensureAvailable();
-        return proxy.getServerKeys(acc);
-    }
-
-    /**
-     * Returns the server-side principal name associated with the KerberosKey.
-     */
-    public static String getServerPrincipalName(SecretKey kerberosKey) {
-        ensureAvailable();
-        return proxy.getServerPrincipalName(kerberosKey);
-    }
-
-    /**
-     * Returns the hostname embedded in the principal name.
-     */
-    public static String getPrincipalHostName(Principal principal) {
-        ensureAvailable();
-        return proxy.getPrincipalHostName(principal);
-    }
-
-    /**
-     * Returns a ServicePermission for the principal name and action.
-     */
-    public static Permission getServicePermission(String principalName,
-            String action) {
-        ensureAvailable();
-        return proxy.getServicePermission(principalName, action);
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/Krb5Proxy.java b/ojluni/src/main/java/sun/security/ssl/Krb5Proxy.java
deleted file mode 100755
index 14a1501..0000000
--- a/ojluni/src/main/java/sun/security/ssl/Krb5Proxy.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.security.AccessControlContext;
-import java.security.Permission;
-import java.security.Principal;
-import javax.crypto.SecretKey;
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginException;
-
-/**
- * An interface to a subset of the Kerberos APIs to avoid a static dependency
- * on the types defined by these APIs.
- */
-public interface Krb5Proxy {
-
-    /**
-     * Returns the Subject associated with the client-side of the SSL socket.
-     */
-    Subject getClientSubject(AccessControlContext acc) throws LoginException;
-
-    /**
-     * Returns the Subject associated with the server-side of the SSL socket.
-     */
-    Subject getServerSubject(AccessControlContext acc) throws LoginException;
-
-
-    /**
-     * Returns the KerberosKeys for the default server-side principal.
-     */
-    SecretKey[] getServerKeys(AccessControlContext acc) throws LoginException;
-
-    /**
-     * Returns the server-side principal name associated with the KerberosKey.
-     */
-    String getServerPrincipalName(SecretKey kerberosKey);
-
-    /**
-     * Returns the hostname embedded in the principal name.
-     */
-    String getPrincipalHostName(Principal principal);
-
-    /**
-     * Returns a ServicePermission for the principal name and action.
-     */
-    Permission getServicePermission(String principalName, String action);
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/MAC.java b/ojluni/src/main/java/sun/security/ssl/MAC.java
deleted file mode 100755
index e491cc3..0000000
--- a/ojluni/src/main/java/sun/security/ssl/MAC.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-
-import java.nio.ByteBuffer;
-
-import javax.crypto.Mac;
-import javax.crypto.SecretKey;
-
-import sun.security.ssl.CipherSuite.MacAlg;
-import static sun.security.ssl.CipherSuite.*;
-
-/**
- * This class computes the "Message Authentication Code" (MAC) for each
- * SSL message.  This is essentially a shared-secret signature, used to
- * provide integrity protection for SSL messages.  The MAC is actually
- * one of several keyed hashes, as associated with the cipher suite and
- * protocol version.  (SSL v3.0 uses one construct, TLS uses another.)
- * <P>
- * NOTE: MAC computation is the only place in the SSL protocol that the
- * sequence number is used.  It's also reset to zero with each change of
- * a cipher spec, so this is the only place this state is needed.
- *
- * @author David Brownell
- * @author Andreas Sterbenz
- */
-final class MAC {
-
-    final static MAC NULL = new MAC();
-
-    // Value of the null MAC is fixed
-    private static final byte nullMAC[] = new byte[0];
-
-    // internal identifier for the MAC algorithm
-    private final MacAlg        macAlg;
-
-    // stuff defined by the kind of MAC algorithm
-    private final int           macSize;
-
-    // JCE Mac object
-    private final Mac mac;
-
-    // byte array containing the additional information we MAC in each record
-    // (see below)
-    private final byte[] block;
-
-    // sequence number + record type + + record length
-    private static final int BLOCK_SIZE_SSL = 8 + 1 + 2;
-
-    // sequence number + record type + protocol version + record length
-    private static final int BLOCK_SIZE_TLS = 8 + 1 + 2 + 2;
-
-    // offset of record type in block
-    private static final int BLOCK_OFFSET_TYPE    = 8;
-
-    // offset of protocol version number in block (TLS only)
-    private static final int BLOCK_OFFSET_VERSION = 8 + 1;
-
-    private MAC() {
-        macSize = 0;
-        macAlg = M_NULL;
-        mac = null;
-        block = null;
-    }
-
-    /**
-     * Set up, configured for the given SSL/TLS MAC type and version.
-     */
-    MAC(MacAlg macAlg, ProtocolVersion protocolVersion, SecretKey key)
-            throws NoSuchAlgorithmException, InvalidKeyException {
-        this.macAlg = macAlg;
-        this.macSize = macAlg.size;
-
-        String algorithm;
-        boolean tls = (protocolVersion.v >= ProtocolVersion.TLS10.v);
-
-        if (macAlg == M_MD5) {
-            algorithm = tls ? "HmacMD5" : "SslMacMD5";
-        } else if (macAlg == M_SHA) {
-            algorithm = tls ? "HmacSHA1" : "SslMacSHA1";
-        } else if (macAlg == M_SHA256) {
-            algorithm = "HmacSHA256";    // TLS 1.2+
-        } else if (macAlg == M_SHA384) {
-            algorithm = "HmacSHA384";    // TLS 1.2+
-        } else {
-            throw new RuntimeException("Unknown Mac " + macAlg);
-        }
-
-        mac = JsseJce.getMac(algorithm);
-        mac.init(key);
-
-        if (tls) {
-            block = new byte[BLOCK_SIZE_TLS];
-            block[BLOCK_OFFSET_VERSION]   = protocolVersion.major;
-            block[BLOCK_OFFSET_VERSION+1] = protocolVersion.minor;
-        } else {
-            block = new byte[BLOCK_SIZE_SSL];
-        }
-    }
-
-    /**
-     * Returns the length of the MAC.
-     */
-    int MAClen() {
-        return macSize;
-    }
-
-    /**
-     * Returns the hash function block length of the MAC alorithm.
-     */
-    int hashBlockLen() {
-        return macAlg.hashBlockSize;
-    }
-
-    /**
-     * Returns the hash function minimal padding length of the MAC alorithm.
-     */
-    int minimalPaddingLen() {
-        return macAlg.minimalPaddingSize;
-    }
-
-    /**
-     * Computes and returns the MAC for the data in this byte array.
-     *
-     * @param type record type
-     * @param buf compressed record on which the MAC is computed
-     * @param offset start of compressed record data
-     * @param len the size of the compressed record
-     * @param isSimulated if true, simulate the the MAC computation
-     */
-    final byte[] compute(byte type, byte buf[],
-            int offset, int len, boolean isSimulated) {
-        return compute(type, null, buf, offset, len, isSimulated);
-    }
-
-    /**
-     * Compute and returns the MAC for the remaining data
-     * in this ByteBuffer.
-     *
-     * On return, the bb position == limit, and limit will
-     * have not changed.
-     *
-     * @param type record type
-     * @param bb a ByteBuffer in which the position and limit
-     *          demarcate the data to be MAC'd.
-     * @param isSimulated if true, simulate the the MAC computation
-     */
-    final byte[] compute(byte type, ByteBuffer bb, boolean isSimulated) {
-        return compute(type, bb, null, 0, bb.remaining(), isSimulated);
-    }
-
-    /**
-     * Check whether the sequence number is close to wrap
-     *
-     * Sequence numbers are of type uint64 and may not exceed 2^64-1.
-     * Sequence numbers do not wrap. When the sequence number is near
-     * to wrap, we need to close the connection immediately.
-     */
-    final boolean seqNumOverflow() {
-        /*
-         * Conservatively, we don't allow more records to be generated
-         * when there are only 2^8 sequence numbers left.
-         */
-        return (block != null && mac != null &&
-                block[0] == (byte)0xFF && block[1] == (byte)0xFF &&
-                block[2] == (byte)0xFF && block[3] == (byte)0xFF &&
-                block[4] == (byte)0xFF && block[5] == (byte)0xFF &&
-                block[6] == (byte)0xFF);
-    }
-
-    /*
-     * Check whether to renew the sequence number
-     *
-     * Sequence numbers are of type uint64 and may not exceed 2^64-1.
-     * Sequence numbers do not wrap.  If a TLS
-     * implementation would need to wrap a sequence number, it must
-     * renegotiate instead.
-     */
-    final boolean seqNumIsHuge() {
-        /*
-         * Conservatively, we should ask for renegotiation when there are
-         * only 2^48 sequence numbers left.
-         */
-        return (block != null && mac != null &&
-                block[0] == (byte)0xFF && block[1] == (byte)0xFF);
-    }
-
-    // increment the sequence number in the block array
-    // it is a 64-bit number stored in big-endian format
-    private void incrementSequenceNumber() {
-        int k = 7;
-        while ((k >= 0) && (++block[k] == 0)) {
-            k--;
-        }
-    }
-
-    /*
-     * Compute based on either buffer type, either bb.position/limit
-     * or buf/offset/len.
-     */
-    private byte[] compute(byte type, ByteBuffer bb, byte[] buf,
-            int offset, int len, boolean isSimulated) {
-
-        if (macSize == 0) {
-            return nullMAC;
-        }
-
-        // MUST NOT increase the sequence number for a simulated computation.
-        if (!isSimulated) {
-            block[BLOCK_OFFSET_TYPE] = type;
-            block[block.length - 2]  = (byte)(len >> 8);
-            block[block.length - 1]  = (byte)(len     );
-
-            mac.update(block);
-            incrementSequenceNumber();
-        }
-
-        // content
-        if (bb != null) {
-            mac.update(bb);
-        } else {
-            mac.update(buf, offset, len);
-        }
-
-        return mac.doFinal();
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/OutputRecord.java b/ojluni/src/main/java/sun/security/ssl/OutputRecord.java
deleted file mode 100755
index 012816d..0000000
--- a/ojluni/src/main/java/sun/security/ssl/OutputRecord.java
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.nio.*;
-import java.util.Arrays;
-
-import javax.net.ssl.SSLException;
-import sun.misc.HexDumpEncoder;
-
-
-/**
- * SSL 3.0 records, as written to a TCP stream.
- *
- * Each record has a message area that starts out with data supplied by the
- * application.  It may grow/shrink due to compression and will be modified
- * in place for mac-ing and encryption.
- *
- * Handshake records have additional needs, notably accumulation of a set
- * of hashes which are used to establish that handshaking was done right.
- * Handshake records usually have several handshake messages each, and we
- * need message-level control over what's hashed.
- *
- * @author David Brownell
- */
-class OutputRecord extends ByteArrayOutputStream implements Record {
-
-    private HandshakeHash       handshakeHash;
-    private int                 lastHashed;
-    private boolean             firstMessage;
-    final private byte          contentType;
-
-    // current protocol version, sent as record version
-    ProtocolVersion     protocolVersion;
-
-    // version for the ClientHello message. Only relevant if this is a
-    // client handshake record. If set to ProtocolVersion.SSL20Hello,
-    // the V3 client hello is converted to V2 format.
-    private ProtocolVersion     helloVersion;
-
-    /* Class and subclass dynamic debugging support */
-    static final Debug debug = Debug.getInstance("ssl");
-
-    /*
-     * Default constructor makes a record supporting the maximum
-     * SSL record size.  It allocates the header bytes directly.
-     *
-     * @param type the content type for the record
-     */
-    OutputRecord(byte type, int size) {
-        super(size);
-        this.protocolVersion = ProtocolVersion.DEFAULT;
-        this.helloVersion = ProtocolVersion.DEFAULT_HELLO;
-        firstMessage = true;
-        count = headerSize;
-        contentType = type;
-        lastHashed = count;
-    }
-
-    OutputRecord(byte type) {
-        this(type, recordSize(type));
-    }
-
-    /**
-     * Get the size of the buffer we need for records of the specified
-     * type.
-     */
-    private static int recordSize(byte type) {
-        if ((type == ct_change_cipher_spec) || (type == ct_alert)) {
-            return maxAlertRecordSize;
-        } else {
-            return maxRecordSize;
-        }
-    }
-
-    /*
-     * Updates the SSL version of this record.
-     */
-    synchronized void setVersion(ProtocolVersion protocolVersion) {
-        this.protocolVersion = protocolVersion;
-    }
-
-    /*
-     * Updates helloVersion of this record.
-     */
-    synchronized void setHelloVersion(ProtocolVersion helloVersion) {
-        this.helloVersion = helloVersion;
-    }
-
-    /*
-     * Reset the record so that it can be refilled, starting
-     * immediately after the header.
-     */
-    public synchronized void reset() {
-        super.reset();
-        count = headerSize;
-        lastHashed = count;
-    }
-
-    /*
-     * For handshaking, we need to be able to hash every byte above the
-     * record marking layer.  This is where we're guaranteed to see those
-     * bytes, so this is where we can hash them.
-     */
-    void setHandshakeHash(HandshakeHash handshakeHash) {
-        assert(contentType == ct_handshake);
-        this.handshakeHash = handshakeHash;
-    }
-
-    /*
-     * We hash (the plaintext) on demand.  There is one place where
-     * we want to access the hash in the middle of a record:  client
-     * cert message gets hashed, and part of the same record is the
-     * client cert verify message which uses that hash.  So we track
-     * how much of each record we've hashed so far.
-     */
-    void doHashes() {
-        int len = count - lastHashed;
-
-        if (len > 0) {
-            hashInternal(buf, lastHashed, len);
-            lastHashed = count;
-        }
-    }
-
-    /*
-     * Need a helper function so we can hash the V2 hello correctly
-     */
-    private void hashInternal(byte buf [], int offset, int len) {
-        if (debug != null && Debug.isOn("data")) {
-            try {
-                HexDumpEncoder hd = new HexDumpEncoder();
-
-                System.out.println("[write] MD5 and SHA1 hashes:  len = "
-                    + len);
-                hd.encodeBuffer(new ByteArrayInputStream(buf,
-                    lastHashed, len), System.out);
-            } catch (IOException e) { }
-        }
-
-        handshakeHash.update(buf, lastHashed, len);
-        lastHashed = count;
-    }
-
-    /*
-     * Return true iff the record is empty -- to avoid doing the work
-     * of sending empty records over the network.
-     */
-    boolean isEmpty() {
-        return count == headerSize;
-    }
-
-    /*
-     * Return true if the record is of a given alert.
-     */
-    boolean isAlert(byte description) {
-        // An alert is defined with a two bytes struct,
-        // {byte level, byte description}, following after the header bytes.
-        if (count > (headerSize + 1) && contentType == ct_alert) {
-            return buf[headerSize + 1] == description;
-        }
-
-        return false;
-    }
-
-    /*
-     * Compute the MAC and append it to this record.  In case we
-     * are automatically flushing a handshake stream, make sure we
-     * have hashed the message first.
-     */
-    void addMAC(MAC signer) throws IOException {
-        //
-        // when we support compression, hashing can't go here
-        // since it'll need to be done on the uncompressed data,
-        // and the MAC applies to the compressed data.
-        //
-        if (contentType == ct_handshake) {
-            doHashes();
-        }
-        if (signer.MAClen() != 0) {
-            byte[] hash = signer.compute(contentType, buf,
-                    headerSize, count - headerSize, false);
-            write(hash);
-        }
-    }
-
-    /*
-     * Encrypt ... length may grow due to block cipher padding
-     */
-    void encrypt(CipherBox box) {
-        int len = count - headerSize;
-        count = headerSize + box.encrypt(buf, headerSize, len);
-    }
-
-
-    /*
-     * Tell how full the buffer is ... for filling it with application or
-     * handshake data.
-     */
-    final int availableDataBytes() {
-        int dataSize = count - headerSize;
-        return maxDataSize - dataSize;
-    }
-
-    /*
-     * Increases the capacity if necessary to ensure that it can hold
-     * at least the number of elements specified by the minimum
-     * capacity argument.
-     *
-     * Note that the increased capacity is only can be used for held
-     * record buffer. Please DO NOT update the availableDataBytes()
-     * according to the expended buffer capacity.
-     *
-     * @see availableDataBytes()
-     */
-    private void ensureCapacity(int minCapacity) {
-        // overflow-conscious code
-        if (minCapacity > buf.length) {
-            buf = Arrays.copyOf(buf, minCapacity);
-        }
-    }
-
-    /*
-     * Return the type of SSL record that's buffered here.
-     */
-    final byte contentType() {
-        return contentType;
-    }
-
-    /*
-     * Write the record out on the stream.  Note that you must have (in
-     * order) compressed the data, appended the MAC, and encrypted it in
-     * order for the record to be understood by the other end.  (Some of
-     * those steps will be null early in handshaking.)
-     *
-     * Note that this does no locking for the connection, it's required
-     * that synchronization be done elsewhere.  Also, this does its work
-     * in a single low level write, for efficiency.
-     */
-    void write(OutputStream s, boolean holdRecord,
-            ByteArrayOutputStream heldRecordBuffer) throws IOException {
-        /*
-         * Don't emit content-free records.  (Even change cipher spec
-         * messages have a byte of data!)
-         */
-        if (count == headerSize) {
-            return;
-        }
-
-        int length = count - headerSize;
-        // "should" really never write more than about 14 Kb...
-        if (length < 0) {
-            throw new SSLException("output record size too small: "
-                + length);
-        }
-
-        if (debug != null
-                && (Debug.isOn("record") || Debug.isOn("handshake"))) {
-            if ((debug != null && Debug.isOn("record"))
-                    || contentType() == ct_change_cipher_spec)
-                System.out.println(Thread.currentThread().getName()
-                    // v3.0/v3.1 ...
-                    + ", WRITE: " + protocolVersion
-                    + " " + InputRecord.contentName(contentType())
-                    + ", length = " + length);
-        }
-
-        /*
-         * If this is the initial ClientHello on this connection and
-         * we're not trying to resume a (V3) session then send a V2
-         * ClientHello instead so we can detect V2 servers cleanly.
-         */
-         if (firstMessage && useV2Hello()) {
-            byte[] v3Msg = new byte[length - 4];
-            System.arraycopy(buf, headerSize + 4, v3Msg, 0, v3Msg.length);
-            V3toV2ClientHello(v3Msg);
-            handshakeHash.reset();
-            lastHashed = 2;
-            doHashes();
-            if (debug != null && Debug.isOn("record"))  {
-                System.out.println(
-                    Thread.currentThread().getName()
-                    + ", WRITE: SSLv2 client hello message"
-                    + ", length = " + (count - 2)); // 2 byte SSLv2 header
-            }
-        } else {
-            /*
-             * Fill out the header, write it and the message.
-             */
-            buf[0] = contentType;
-            buf[1] = protocolVersion.major;
-            buf[2] = protocolVersion.minor;
-            buf[3] = (byte)(length >> 8);
-            buf[4] = (byte)(length);
-        }
-        firstMessage = false;
-
-        /*
-         * The upper levels may want us to delay sending this packet so
-         * multiple TLS Records can be sent in one (or more) TCP packets.
-         * If so, add this packet to the heldRecordBuffer.
-         *
-         * NOTE:  all writes have been synchronized by upper levels.
-         */
-        int debugOffset = 0;
-        if (holdRecord) {
-            /*
-             * If holdRecord is true, we must have a heldRecordBuffer.
-             *
-             * Don't worry about the override of writeBuffer(), because
-             * when holdRecord is true, the implementation in this class
-             * will be used.
-             */
-            writeBuffer(heldRecordBuffer, buf, 0, count, debugOffset);
-        } else {
-            // It's time to send, do we have buffered data?
-            // May or may not have a heldRecordBuffer.
-            if (heldRecordBuffer != null && heldRecordBuffer.size() > 0) {
-                int heldLen = heldRecordBuffer.size();
-
-                // Ensure the capacity of this buffer.
-                ensureCapacity(count + heldLen);
-
-                // Slide everything in the buffer to the right.
-                System.arraycopy(buf, 0, buf, heldLen, count);
-
-                // Prepend the held record to the buffer.
-                System.arraycopy(
-                    heldRecordBuffer.toByteArray(), 0, buf, 0, heldLen);
-                count += heldLen;
-
-                // Clear the held buffer.
-                heldRecordBuffer.reset();
-
-                // The held buffer has been dumped, set the debug dump offset.
-                debugOffset = heldLen;
-            }
-            writeBuffer(s, buf, 0, count, debugOffset);
-        }
-
-        reset();
-    }
-
-    /*
-     * Actually do the write here.  For SSLEngine's HS data,
-     * we'll override this method and let it take the appropriate
-     * action.
-     */
-    void writeBuffer(OutputStream s, byte [] buf, int off, int len,
-            int debugOffset) throws IOException {
-
-        s.write(buf, off, len);
-        s.flush();
-
-        // Output only the record from the specified debug offset.
-        if (debug != null && Debug.isOn("packet")) {
-            try {
-                HexDumpEncoder hd = new HexDumpEncoder();
-                ByteBuffer bb = ByteBuffer.wrap(
-                        buf, off + debugOffset, len - debugOffset);
-
-                System.out.println("[Raw write]: length = " +
-                    bb.remaining());
-                hd.encodeBuffer(bb, System.out);
-            } catch (IOException e) { }
-        }
-    }
-
-    /*
-     * Return whether the buffer contains a ClientHello message that should
-     * be converted to V2 format.
-     */
-    private boolean useV2Hello() {
-        return firstMessage
-            && (helloVersion == ProtocolVersion.SSL20Hello)
-            && (contentType == ct_handshake)
-            && (buf[5] == HandshakeMessage.ht_client_hello)
-            && (buf[headerSize + 4+2+32] == 0); // V3 session ID is empty
-    }
-
-    /*
-     * Detect "old" servers which are capable of SSL V2.0 protocol ... for
-     * example, Netscape Commerce 1.0 servers.  The V3 message is in the
-     * header and the bytes passed as parameter.  This routine translates
-     * the V3 message into an equivalent V2 one.
-     *
-     * Note that the translation will strip off all hello extensions as
-     * SSL V2.0 does not support hello extension.
-     */
-    private void V3toV2ClientHello(byte v3Msg []) throws SSLException {
-        int v3SessionIdLenOffset = 2 + 32; // version + nonce
-        int v3SessionIdLen = v3Msg[v3SessionIdLenOffset];
-        int v3CipherSpecLenOffset = v3SessionIdLenOffset + 1 + v3SessionIdLen;
-        int v3CipherSpecLen = ((v3Msg[v3CipherSpecLenOffset] & 0xff) << 8) +
-          (v3Msg[v3CipherSpecLenOffset + 1] & 0xff);
-        int cipherSpecs = v3CipherSpecLen / 2; // 2 bytes each in V3
-
-        /*
-         * Copy over the cipher specs. We don't care about actually translating
-         * them for use with an actual V2 server since we only talk V3.
-         * Therefore, just copy over the V3 cipher spec values with a leading
-         * 0.
-         */
-        int v3CipherSpecOffset = v3CipherSpecLenOffset + 2; // skip length
-        int v2CipherSpecLen = 0;
-        count = 11;
-        boolean containsRenegoInfoSCSV = false;
-        for (int i = 0; i < cipherSpecs; i++) {
-            byte byte1, byte2;
-
-            byte1 = v3Msg[v3CipherSpecOffset++];
-            byte2 = v3Msg[v3CipherSpecOffset++];
-            v2CipherSpecLen += V3toV2CipherSuite(byte1, byte2);
-            if (!containsRenegoInfoSCSV &&
-                        byte1 == (byte)0x00 && byte2 == (byte)0xFF) {
-                containsRenegoInfoSCSV = true;
-            }
-        }
-
-        if (!containsRenegoInfoSCSV) {
-            v2CipherSpecLen += V3toV2CipherSuite((byte)0x00, (byte)0xFF);
-        }
-
-        /*
-         * Build the first part of the V3 record header from the V2 one
-         * that's now buffered up.  (Lengths are fixed up later).
-         */
-        buf[2] = HandshakeMessage.ht_client_hello;
-        buf[3] = v3Msg[0];      // major version
-        buf[4] = v3Msg[1];      // minor version
-        buf[5] = (byte)(v2CipherSpecLen >>> 8);
-        buf[6] = (byte)v2CipherSpecLen;
-        buf[7] = 0;
-        buf[8] = 0;             // always no session
-        buf[9] = 0;
-        buf[10] = 32;           // nonce length (always 32 in V3)
-
-        /*
-         * Copy in the nonce.
-         */
-        System.arraycopy(v3Msg, 2, buf, count, 32);
-        count += 32;
-
-        /*
-         * Set the length of the message.
-         */
-        count -= 2; // don't include length field itself
-        buf[0] = (byte)(count >>> 8);
-        buf[0] |= 0x80;
-        buf[1] = (byte)(count);
-        count += 2;
-    }
-
-    /*
-     * Mappings from V3 cipher suite encodings to their pure V2 equivalents.
-     * This is taken from the SSL V3 specification, Appendix E.
-     */
-    private static int[] V3toV2CipherMap1 =
-        {-1, -1, -1, 0x02, 0x01, -1, 0x04, 0x05, -1, 0x06, 0x07};
-    private static int[] V3toV2CipherMap3 =
-        {-1, -1, -1, 0x80, 0x80, -1, 0x80, 0x80, -1, 0x40, 0xC0};
-
-    /*
-     * See which matching pure-V2 cipher specs we need to include.
-     * We are including these not because we are actually prepared
-     * to talk V2 but because the Oracle Web Server insists on receiving
-     * at least 1 "pure V2" cipher suite that it supports and returns an
-     * illegal_parameter alert unless one is present. Rather than mindlessly
-     * claiming to implement all documented pure V2 cipher suites the code below
-     * just claims to implement the V2 cipher suite that is "equivalent"
-     * in terms of cipher algorithm & exportability with the actual V3 cipher
-     * suite that we do support.
-     */
-    private int V3toV2CipherSuite(byte byte1, byte byte2) {
-        buf[count++] = 0;
-        buf[count++] = byte1;
-        buf[count++] = byte2;
-
-        if (((byte2 & 0xff) > 0xA) ||
-                (V3toV2CipherMap1[byte2] == -1)) {
-            return 3;
-        }
-
-        buf[count++] = (byte)V3toV2CipherMap1[byte2];
-        buf[count++] = 0;
-        buf[count++] = (byte)V3toV2CipherMap3[byte2];
-
-        return 6;
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/ProtocolList.java b/ojluni/src/main/java/sun/security/ssl/ProtocolList.java
deleted file mode 100755
index a57a9bd..0000000
--- a/ojluni/src/main/java/sun/security/ssl/ProtocolList.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.util.*;
-
-/**
- * A list of ProtocolVersions. Also maintains the list of supported protocols.
- * Instances of this class are immutable. Some member variables are final
- * and can be accessed directly without method accessors.
- *
- * @author  Andreas Sterbenz
- * @since   1.4.1
- */
-final class ProtocolList {
-
-    // the sorted protocol version list
-    private final ArrayList<ProtocolVersion> protocols;
-
-    private String[] protocolNames;
-
-    // the minimum and maximum ProtocolVersions in this list
-    final ProtocolVersion min, max;
-
-    // the format for the hello version to use
-    final ProtocolVersion helloVersion;
-
-    ProtocolList(String[] names) {
-        this(convert(names));
-    }
-
-    ProtocolList(ArrayList<ProtocolVersion> versions) {
-        this.protocols = versions;
-
-        if ((protocols.size() == 1) &&
-                protocols.contains(ProtocolVersion.SSL20Hello)) {
-            throw new IllegalArgumentException("SSLv2Hello cannot be " +
-                "enabled unless at least one other supported version " +
-                "is also enabled.");
-        }
-
-        if (protocols.size() != 0) {
-            Collections.sort(protocols);
-            min = protocols.get(0);
-            max = protocols.get(protocols.size() - 1);
-            helloVersion = protocols.get(0);
-        } else {
-            min = ProtocolVersion.NONE;
-            max = ProtocolVersion.NONE;
-            helloVersion = ProtocolVersion.NONE;
-        }
-    }
-
-    private static ArrayList<ProtocolVersion> convert(String[] names) {
-        if (names == null) {
-            throw new IllegalArgumentException("Protocols may not be null");
-        }
-
-        ArrayList<ProtocolVersion> versions = new ArrayList<>(3);
-        for (int i = 0; i < names.length; i++ ) {
-            ProtocolVersion version = ProtocolVersion.valueOf(names[i]);
-            if (versions.contains(version) == false) {
-                versions.add(version);
-            }
-        }
-
-        return versions;
-    }
-
-    /**
-     * Return whether this list contains the specified protocol version.
-     * SSLv2Hello is not a real protocol version we support, we always
-     * return false for it.
-     */
-    boolean contains(ProtocolVersion protocolVersion) {
-        if (protocolVersion == ProtocolVersion.SSL20Hello) {
-            return false;
-        }
-        return protocols.contains(protocolVersion);
-    }
-
-    /**
-     * Return a reference to the internal Collection of CipherSuites.
-     * The Collection MUST NOT be modified.
-     */
-    Collection<ProtocolVersion> collection() {
-        return protocols;
-    }
-
-    /**
-     * Select a protocol version from the list.
-     *
-     * Return the lower of the protocol version of that suggested by
-     * the <code>protocolVersion</code> and the highest version of this
-     * protocol list, or null if no protocol version is available.
-     *
-     * The method is used by TLS server to negotiated the protocol
-     * version between client suggested protocol version in the
-     * client hello and protocol versions supported by the server.
-     */
-    ProtocolVersion selectProtocolVersion(ProtocolVersion protocolVersion) {
-        ProtocolVersion selectedVersion = null;
-        for (ProtocolVersion pv : protocols) {
-            if (pv.v > protocolVersion.v) {
-                break;  // Safe to break here as this.protocols is sorted
-            }
-            selectedVersion = pv;
-        }
-
-        return selectedVersion;
-    }
-
-    /**
-     * Return an array with the names of the ProtocolVersions in this list.
-     */
-    synchronized String[] toStringArray() {
-        if (protocolNames == null) {
-            protocolNames = new String[protocols.size()];
-            int i = 0;
-            for (ProtocolVersion version : protocols) {
-                protocolNames[i++] = version.name;
-            }
-        }
-        return protocolNames.clone();
-    }
-
-    public String toString() {
-        return protocols.toString();
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/ProtocolVersion.java b/ojluni/src/main/java/sun/security/ssl/ProtocolVersion.java
deleted file mode 100755
index 77c102a..0000000
--- a/ojluni/src/main/java/sun/security/ssl/ProtocolVersion.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-/**
- * Type safe enum for an SSL/TLS protocol version. Instances are obtained
- * using the static factory methods or by referencing the static members
- * in this class. Member variables are final and can be accessed without
- * accessor methods.
- *
- * There is only ever one instance per supported protocol version, this
- * means == can be used for comparision instead of equals() if desired.
- *
- * Checks for a particular version number should generally take this form:
- *
- * if (protocolVersion.v >= ProtocolVersion.TLS10) {
- *   // TLS 1.0 code goes here
- * } else {
- *   // SSL 3.0 code here
- * }
- *
- * @author  Andreas Sterbenz
- * @since   1.4.1
- */
-public final class ProtocolVersion implements Comparable<ProtocolVersion> {
-
-    // The limit of maximum protocol version
-    final static int LIMIT_MAX_VALUE = 0xFFFF;
-
-    // The limit of minimum protocol version
-    final static int LIMIT_MIN_VALUE = 0x0000;
-
-    // Dummy protocol version value for invalid SSLSession
-    final static ProtocolVersion NONE = new ProtocolVersion(-1, "NONE");
-
-    // If enabled, send/ accept SSLv2 hello messages
-    final static ProtocolVersion SSL20Hello = new ProtocolVersion(0x0002,
-                                                                "SSLv2Hello");
-
-    // SSL 3.0
-    final static ProtocolVersion SSL30 = new ProtocolVersion(0x0300, "SSLv3");
-
-    // TLS 1.0
-    final static ProtocolVersion TLS10 = new ProtocolVersion(0x0301, "TLSv1");
-
-    // TLS 1.1
-    final static ProtocolVersion TLS11 = new ProtocolVersion(0x0302, "TLSv1.1");
-
-    // TLS 1.2
-    final static ProtocolVersion TLS12 = new ProtocolVersion(0x0303, "TLSv1.2");
-
-    private static final boolean FIPS = SunJSSE.isFIPS();
-
-    // minimum version we implement (SSL 3.0)
-    final static ProtocolVersion MIN = FIPS ? TLS10 : SSL30;
-
-    // maximum version we implement (TLS 1.2)
-    final static ProtocolVersion MAX = TLS12;
-
-    // ProtocolVersion to use by default (TLS 1.0)
-    final static ProtocolVersion DEFAULT = TLS10;
-
-    // Default version for hello messages (SSLv2Hello)
-    final static ProtocolVersion DEFAULT_HELLO = FIPS ? TLS10 : SSL30;
-
-    // version in 16 bit MSB format as it appears in records and
-    // messages, i.e. 0x0301 for TLS 1.0
-    public final int v;
-
-    // major and minor version
-    public final byte major, minor;
-
-    // name used in JSSE (e.g. TLSv1 for TLS 1.0)
-    final String name;
-
-    // private
-    private ProtocolVersion(int v, String name) {
-        this.v = v;
-        this.name = name;
-        major = (byte)(v >>> 8);
-        minor = (byte)(v & 0xff);
-    }
-
-    // private
-    private static ProtocolVersion valueOf(int v) {
-        if (v == SSL30.v) {
-            return SSL30;
-        } else if (v == TLS10.v) {
-            return TLS10;
-        } else if (v == TLS11.v) {
-            return TLS11;
-        } else if (v == TLS12.v) {
-            return TLS12;
-        } else if (v == SSL20Hello.v) {
-            return SSL20Hello;
-        } else {
-            int major = (v >>> 8) & 0xff;
-            int minor = v & 0xff;
-            return new ProtocolVersion(v, "Unknown-" + major + "." + minor);
-        }
-    }
-
-    /**
-     * Return a ProtocolVersion with the specified major and minor version
-     * numbers. Never throws exceptions.
-     */
-    public static ProtocolVersion valueOf(int major, int minor) {
-        major &= 0xff;
-        minor &= 0xff;
-        int v = (major << 8) | minor;
-        return valueOf(v);
-    }
-
-    /**
-     * Return a ProtocolVersion for the given name.
-     *
-     * @exception IllegalArgumentException if name is null or does not
-     * identify a supported protocol
-     */
-    static ProtocolVersion valueOf(String name) {
-        if (name == null) {
-            throw new IllegalArgumentException("Protocol cannot be null");
-        }
-
-        if (FIPS && (name.equals(SSL30.name) || name.equals(SSL20Hello.name))) {
-            throw new IllegalArgumentException
-                ("Only TLS 1.0 or later allowed in FIPS mode");
-        }
-
-        if (name.equals(SSL30.name)) {
-            return SSL30;
-        } else if (name.equals(TLS10.name)) {
-            return TLS10;
-        } else if (name.equals(TLS11.name)) {
-            return TLS11;
-        } else if (name.equals(TLS12.name)) {
-            return TLS12;
-        } else if (name.equals(SSL20Hello.name)) {
-            return SSL20Hello;
-        } else {
-            throw new IllegalArgumentException(name);
-        }
-    }
-
-    public String toString() {
-        return name;
-    }
-
-    /**
-     * Compares this object with the specified object for order.
-     */
-    public int compareTo(ProtocolVersion protocolVersion) {
-        return this.v - protocolVersion.v;
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/RSAClientKeyExchange.java b/ojluni/src/main/java/sun/security/ssl/RSAClientKeyExchange.java
deleted file mode 100755
index f8e501e..0000000
--- a/ojluni/src/main/java/sun/security/ssl/RSAClientKeyExchange.java
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.security.*;
-import java.security.interfaces.*;
-
-import javax.crypto.*;
-import javax.crypto.spec.*;
-
-import javax.net.ssl.*;
-
-import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
-import sun.security.util.KeyUtil;
-
-/**
- * This is the client key exchange message (CLIENT --> SERVER) used with
- * all RSA key exchanges; it holds the RSA-encrypted pre-master secret.
- *
- * The message is encrypted using PKCS #1 block type 02 encryption with the
- * server's public key.  The padding and resulting message size is a function
- * of this server's public key modulus size, but the pre-master secret is
- * always exactly 48 bytes.
- *
- */
-final class RSAClientKeyExchange extends HandshakeMessage {
-
-    /**
-     * The TLS spec says that the version in the RSA premaster secret must
-     * be the maximum version supported by the client (i.e. the version it
-     * requested in its client hello version). However, we (and other
-     * implementations) used to send the active negotiated version. The
-     * system property below allows to toggle the behavior.
-     */
-    private final static String PROP_NAME =
-                                "com.sun.net.ssl.rsaPreMasterSecretFix";
-
-    /*
-     * Default is "false" (old behavior) for compatibility reasons in
-     * SSLv3/TLSv1.  Later protocols (TLSv1.1+) do not use this property.
-     */
-    private final static boolean rsaPreMasterSecretFix =
-                                Debug.getBooleanProperty(PROP_NAME, false);
-
-    /*
-     * The following field values were encrypted with the server's public
-     * key (or temp key from server key exchange msg) and are presented
-     * here in DECRYPTED form.
-     */
-    private ProtocolVersion protocolVersion; // preMaster [0,1]
-    SecretKey preMaster;
-    private byte[] encrypted;           // same size as public modulus
-
-    /*
-     * Client randomly creates a pre-master secret and encrypts it
-     * using the server's RSA public key; only the server can decrypt
-     * it, using its RSA private key.  Result is the same size as the
-     * server's public key, and uses PKCS #1 block format 02.
-     */
-    RSAClientKeyExchange(ProtocolVersion protocolVersion,
-            ProtocolVersion maxVersion,
-            SecureRandom generator, PublicKey publicKey) throws IOException {
-        if (publicKey.getAlgorithm().equals("RSA") == false) {
-            throw new SSLKeyException("Public key not of type RSA");
-        }
-        this.protocolVersion = protocolVersion;
-
-        int major, minor;
-
-        if (rsaPreMasterSecretFix || maxVersion.v >= ProtocolVersion.TLS11.v) {
-            major = maxVersion.major;
-            minor = maxVersion.minor;
-        } else {
-            major = protocolVersion.major;
-            minor = protocolVersion.minor;
-        }
-
-        try {
-            String s = ((protocolVersion.v >= ProtocolVersion.TLS12.v) ?
-                "SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret");
-            KeyGenerator kg = JsseJce.getKeyGenerator(s);
-            kg.init(new TlsRsaPremasterSecretParameterSpec(major, minor),
-                    generator);
-            preMaster = kg.generateKey();
-
-            Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1);
-            cipher.init(Cipher.WRAP_MODE, publicKey, generator);
-            encrypted = cipher.wrap(preMaster);
-        } catch (GeneralSecurityException e) {
-            throw (SSLKeyException)new SSLKeyException
-                                ("RSA premaster secret error").initCause(e);
-        }
-    }
-
-    /*
-     * Server gets the PKCS #1 (block format 02) data, decrypts
-     * it with its private key.
-     */
-    RSAClientKeyExchange(ProtocolVersion currentVersion,
-            ProtocolVersion maxVersion,
-            SecureRandom generator, HandshakeInStream input,
-            int messageSize, PrivateKey privateKey) throws IOException {
-
-        if (privateKey.getAlgorithm().equals("RSA") == false) {
-            throw new SSLKeyException("Private key not of type RSA");
-        }
-
-        if (currentVersion.v >= ProtocolVersion.TLS10.v) {
-            encrypted = input.getBytes16();
-        } else {
-            encrypted = new byte [messageSize];
-            if (input.read(encrypted) != messageSize) {
-                throw new SSLProtocolException
-                        ("SSL: read PreMasterSecret: short read");
-            }
-        }
-
-        try {
-            Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1);
-            cipher.init(Cipher.UNWRAP_MODE, privateKey);
-            preMaster = (SecretKey)cipher.unwrap(encrypted,
-                                "TlsRsaPremasterSecret", Cipher.SECRET_KEY);
-
-            // polish the premaster secret
-            preMaster = polishPreMasterSecretKey(currentVersion, maxVersion,
-                                                generator, preMaster, null);
-        } catch (Exception e) {
-            // polish the premaster secret
-            preMaster =
-                    polishPreMasterSecretKey(currentVersion, maxVersion,
-                                                generator, null, e);
-        }
-    }
-
-    /**
-     * To avoid vulnerabilities described by section 7.4.7.1, RFC 5246,
-     * treating incorrectly formatted message blocks and/or mismatched
-     * version numbers in a manner indistinguishable from correctly
-     * formatted RSA blocks.
-     *
-     * RFC 5246 describes the approach as :
-     *
-     *  1. Generate a string R of 46 random bytes
-     *
-     *  2. Decrypt the message to recover the plaintext M
-     *
-     *  3. If the PKCS#1 padding is not correct, or the length of message
-     *     M is not exactly 48 bytes:
-     *        pre_master_secret = ClientHello.client_version || R
-     *     else If ClientHello.client_version <= TLS 1.0, and version
-     *     number check is explicitly disabled:
-     *        pre_master_secret = M
-     *     else:
-     *        pre_master_secret = ClientHello.client_version || M[2..47]
-     */
-    private SecretKey polishPreMasterSecretKey(ProtocolVersion currentVersion,
-            ProtocolVersion clientHelloVersion, SecureRandom generator,
-            SecretKey secretKey, Exception failoverException) {
-
-        this.protocolVersion = clientHelloVersion;
-
-        if (failoverException == null && secretKey != null) {
-            // check the length
-            byte[] encoded = secretKey.getEncoded();
-            if (encoded == null) {      // unable to get the encoded key
-                if (debug != null && Debug.isOn("handshake")) {
-                    System.out.println(
-                        "unable to get the plaintext of the premaster secret");
-                }
-
-                int keySize = KeyUtil.getKeySize(secretKey);
-                if (keySize > 0 && keySize != 384) {       // 384 = 48 * 8
-                    if (debug != null && Debug.isOn("handshake")) {
-                        System.out.println(
-                            "incorrect length of premaster secret: " +
-                            (keySize/8));
-                    }
-
-                    return generateDummySecret(clientHelloVersion);
-                }
-
-                // The key size is exactly 48 bytes or not accessible.
-                //
-                // Conservatively, pass the checking to master secret
-                // calculation.
-                return secretKey;
-            } else if (encoded.length == 48) {
-                // check the version
-                if (clientHelloVersion.major == encoded[0] &&
-                    clientHelloVersion.minor == encoded[1]) {
-
-                    return secretKey;
-                } else if (clientHelloVersion.v <= ProtocolVersion.TLS10.v &&
-                           currentVersion.major == encoded[0] &&
-                           currentVersion.minor == encoded[1]) {
-                    /*
-                     * For compatibility, we maintain the behavior that the
-                     * version in pre_master_secret can be the negotiated
-                     * version for TLS v1.0 and SSL v3.0.
-                     */
-                    this.protocolVersion = currentVersion;
-                    return secretKey;
-                }
-
-                if (debug != null && Debug.isOn("handshake")) {
-                    System.out.println("Mismatching Protocol Versions, " +
-                        "ClientHello.client_version is " + clientHelloVersion +
-                        ", while PreMasterSecret.client_version is " +
-                        ProtocolVersion.valueOf(encoded[0], encoded[1]));
-                }
-
-                return generateDummySecret(clientHelloVersion);
-            } else {
-                if (debug != null && Debug.isOn("handshake")) {
-                    System.out.println(
-                        "incorrect length of premaster secret: " +
-                        encoded.length);
-                }
-
-                return generateDummySecret(clientHelloVersion);
-            }
-        }
-
-        if (debug != null && Debug.isOn("handshake") &&
-                    failoverException != null) {
-            System.out.println("Error decrypting premaster secret:");
-            failoverException.printStackTrace(System.out);
-        }
-
-        return generateDummySecret(clientHelloVersion);
-    }
-
-    // generate a premaster secret with the specified version number
-    static SecretKey generateDummySecret(ProtocolVersion version) {
-        if (debug != null && Debug.isOn("handshake")) {
-            System.out.println("Generating a random fake premaster secret");
-        }
-
-        try {
-            String s = ((version.v >= ProtocolVersion.TLS12.v) ?
-                "SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret");
-            KeyGenerator kg = JsseJce.getKeyGenerator(s);
-            kg.init(new TlsRsaPremasterSecretParameterSpec
-                    (version.major, version.minor));
-            return kg.generateKey();
-        } catch (GeneralSecurityException e) {
-            throw new RuntimeException("Could not generate dummy secret", e);
-        }
-    }
-
-    @Override
-    int messageType() {
-        return ht_client_key_exchange;
-    }
-
-    @Override
-    int messageLength() {
-        if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
-            return encrypted.length + 2;
-        } else {
-            return encrypted.length;
-        }
-    }
-
-    @Override
-    void send(HandshakeOutStream s) throws IOException {
-        if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
-            s.putBytes16(encrypted);
-        } else {
-            s.write(encrypted);
-        }
-    }
-
-    @Override
-    void print(PrintStream s) throws IOException {
-        s.println("*** ClientKeyExchange, RSA PreMasterSecret, " +
-                                                        protocolVersion);
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/RSASignature.java b/ojluni/src/main/java/sun/security/ssl/RSASignature.java
deleted file mode 100755
index 5b97bed..0000000
--- a/ojluni/src/main/java/sun/security/ssl/RSASignature.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.util.Arrays;
-
-import java.security.*;
-
-/**
- * Signature implementation for the SSL/TLS RSA Signature variant with both
- * MD5 and SHA-1 MessageDigests. Used for explicit RSA server authentication
- * (RSA signed server key exchange for RSA_EXPORT and DHE_RSA) and RSA client
- * authentication (RSA signed certificate verify message).
- *
- * It conforms to the standard JCA Signature API. It is registered in the
- * SunJSSE provider to avoid more complicated getInstance() code and
- * negative interaction with the JCA mechanisms for hardware providers.
- *
- * The class should be instantiated via the getInstance() method in this class,
- * which returns the implementation from the prefered provider. The internal
- * implementation allows the hashes to be explicitly set, which is required
- * for RSA client authentication. It can be obtained via the
- * getInternalInstance() method.
- *
- * This class is not thread safe.
- *
- */
-public final class RSASignature extends SignatureSpi {
-
-    private final Signature rawRsa;
-    private MessageDigest md5, sha;
-
-    // flag indicating if the MessageDigests are in reset state
-    private boolean isReset;
-
-    public RSASignature() throws NoSuchAlgorithmException {
-        super();
-        rawRsa = JsseJce.getSignature(JsseJce.SIGNATURE_RAWRSA);
-        isReset = true;
-    }
-
-    /**
-     * Get an implementation for the RSA signature. Follows the standard
-     * JCA getInstance() model, so it return the implementation from the
-     * provider with the highest precedence, which may be this class.
-     */
-    static Signature getInstance() throws NoSuchAlgorithmException {
-        return JsseJce.getSignature(JsseJce.SIGNATURE_SSLRSA);
-    }
-
-    /**
-     * Get an internal implementation for the RSA signature. Used for RSA
-     * client authentication, which needs the ability to set the digests
-     * to externally provided values via the setHashes() method.
-     */
-    static Signature getInternalInstance()
-            throws NoSuchAlgorithmException, NoSuchProviderException {
-        return Signature.getInstance(JsseJce.SIGNATURE_SSLRSA, "SunJSSE");
-    }
-
-    /**
-     * Set the MD5 and SHA hashes to the provided objects.
-     */
-    static void setHashes(Signature sig, MessageDigest md5, MessageDigest sha) {
-        sig.setParameter("hashes", new MessageDigest[] {md5, sha});
-    }
-
-    /**
-     * Reset the MessageDigests unless they are already reset.
-     */
-    private void reset() {
-        if (isReset == false) {
-            md5.reset();
-            sha.reset();
-            isReset = true;
-        }
-    }
-
-    private static void checkNull(Key key) throws InvalidKeyException {
-        if (key == null) {
-            throw new InvalidKeyException("Key must not be null");
-        }
-    }
-
-    protected void engineInitVerify(PublicKey publicKey)
-            throws InvalidKeyException {
-        checkNull(publicKey);
-        reset();
-        rawRsa.initVerify(publicKey);
-    }
-
-    protected void engineInitSign(PrivateKey privateKey)
-            throws InvalidKeyException {
-        engineInitSign(privateKey, null);
-    }
-
-    protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
-            throws InvalidKeyException {
-        checkNull(privateKey);
-        reset();
-        rawRsa.initSign(privateKey, random);
-    }
-
-    // lazily initialize the MessageDigests
-    private void initDigests() {
-        if (md5 == null) {
-            md5 = JsseJce.getMD5();
-            sha = JsseJce.getSHA();
-        }
-    }
-
-    protected void engineUpdate(byte b) {
-        initDigests();
-        isReset = false;
-        md5.update(b);
-        sha.update(b);
-    }
-
-    protected void engineUpdate(byte[] b, int off, int len) {
-        initDigests();
-        isReset = false;
-        md5.update(b, off, len);
-        sha.update(b, off, len);
-    }
-
-    private byte[] getDigest() throws SignatureException {
-        try {
-            initDigests();
-            byte[] data = new byte[36];
-            md5.digest(data, 0, 16);
-            sha.digest(data, 16, 20);
-            isReset = true;
-            return data;
-        } catch (DigestException e) {
-            // should never occur
-            throw new SignatureException(e);
-        }
-    }
-
-    protected byte[] engineSign() throws SignatureException {
-        rawRsa.update(getDigest());
-        return rawRsa.sign();
-    }
-
-    protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
-        return engineVerify(sigBytes, 0, sigBytes.length);
-    }
-
-    protected boolean engineVerify(byte[] sigBytes, int offset, int length)
-            throws SignatureException {
-        rawRsa.update(getDigest());
-        return rawRsa.verify(sigBytes, offset, length);
-    }
-
-    protected void engineSetParameter(String param, Object value)
-            throws InvalidParameterException {
-        if (param.equals("hashes") == false) {
-            throw new InvalidParameterException
-                ("Parameter not supported: " + param);
-        }
-        if (value instanceof MessageDigest[] == false) {
-            throw new InvalidParameterException
-                ("value must be MessageDigest[]");
-        }
-        MessageDigest[] digests = (MessageDigest[])value;
-        md5 = digests[0];
-        sha = digests[1];
-    }
-
-    protected Object engineGetParameter(String param)
-            throws InvalidParameterException {
-        throw new InvalidParameterException("Parameters not supported");
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/RandomCookie.java b/ojluni/src/main/java/sun/security/ssl/RandomCookie.java
deleted file mode 100755
index 5f414c4..0000000
--- a/ojluni/src/main/java/sun/security/ssl/RandomCookie.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.security.SecureRandom;
-
-/*
- * RandomCookie ... SSL hands standard format random cookies (nonces)
- * around.  These know how to encode/decode themselves on SSL streams,
- * and can be created and printed.
- *
- * @author David Brownell
- */
-final class RandomCookie {
-
-    byte random_bytes[];  // exactly 32 bytes
-
-    RandomCookie(SecureRandom generator) {
-        long temp = System.currentTimeMillis() / 1000;
-        int gmt_unix_time;
-        if (temp < Integer.MAX_VALUE) {
-            gmt_unix_time = (int) temp;
-        } else {
-            gmt_unix_time = Integer.MAX_VALUE;          // Whoops!
-        }
-
-        random_bytes = new byte[32];
-        generator.nextBytes(random_bytes);
-
-        random_bytes[0] = (byte)(gmt_unix_time >> 24);
-        random_bytes[1] = (byte)(gmt_unix_time >> 16);
-        random_bytes[2] = (byte)(gmt_unix_time >>  8);
-        random_bytes[3] = (byte)gmt_unix_time;
-    }
-
-    RandomCookie(HandshakeInStream m) throws IOException {
-        random_bytes = new byte[32];
-        m.read(random_bytes, 0, 32);
-    }
-
-    void send(HandshakeOutStream out) throws IOException {
-        out.write(random_bytes, 0, 32);
-    }
-
-    void print(PrintStream s) {
-        int i, gmt_unix_time;
-
-        gmt_unix_time = random_bytes[0] << 24;
-        gmt_unix_time += random_bytes[1] << 16;
-        gmt_unix_time += random_bytes[2] << 8;
-        gmt_unix_time += random_bytes[3];
-
-        s.print("GMT: " + gmt_unix_time + " ");
-        s.print("bytes = { ");
-
-        for (i = 4; i < 32; i++) {
-            if (i != 4) {
-                s.print(", ");
-            }
-            s.print(random_bytes[i] & 0x0ff);
-        }
-        s.println(" }");
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/Record.java b/ojluni/src/main/java/sun/security/ssl/Record.java
deleted file mode 100755
index 0494d9a..0000000
--- a/ojluni/src/main/java/sun/security/ssl/Record.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-
-/**
- * SSL/TLS records, as pulled off (and put onto) a TCP stream.  This is
- * the base interface, which defines common information and interfaces
- * used by both Input and Output records.
- *
- * @author David Brownell
- */
-interface Record {
-    /*
-     * There are four SSL record types, which are part of the interface
-     * to this level (along with the maximum record size)
-     *
-     * enum { change_cipher_spec(20), alert(21), handshake(22),
-     *      application_data(23), (255) } ContentType;
-     */
-    static final byte   ct_change_cipher_spec = 20;
-    static final byte   ct_alert = 21;
-    static final byte   ct_handshake = 22;
-    static final byte   ct_application_data = 23;
-
-    static final int    headerSize = 5;         // SSLv3 record header
-    static final int    maxExpansion = 1024;    // for bad compression
-    static final int    trailerSize = 20;       // SHA1 hash size
-    static final int    maxDataSize = 16384;    // 2^14 bytes of data
-    static final int    maxPadding = 256;       // block cipher padding
-    static final int    maxIVLength = 256;      // block length
-
-    /*
-     * SSL has a maximum record size.  It's header, (compressed) data,
-     * padding, and a trailer for the MAC.
-     * Some compression algorithms have rare cases where they expand the data.
-     * As we don't support compression at this time, leave that out.
-     */
-    static final int    maxRecordSize =
-                                      headerSize        // header
-                                    + maxIVLength       // iv
-                                    + maxDataSize       // data
-                                    + maxPadding        // padding
-                                    + trailerSize;      // MAC
-
-    static final boolean enableCBCProtection =
-            Debug.getBooleanProperty("jsse.enableCBCProtection", true);
-
-    /*
-     * For CBC protection in SSL3/TLS1, we break some plaintext into two
-     * packets.  Max application data size for the second packet.
-     */
-    static final int    maxDataSizeMinusOneByteRecord =
-                                  maxDataSize       // max data size
-                                - (                 // max one byte record size
-                                      headerSize    // header
-                                    + maxIVLength   // iv
-                                    + 1             // one byte data
-                                    + maxPadding    // padding
-                                    + trailerSize   // MAC
-                                  );
-
-    /*
-     * The maximum large record size.
-     *
-     * Some SSL/TLS implementations support large fragment upto 2^15 bytes,
-     * such as Microsoft. We support large incoming fragments.
-     *
-     * The maximum large record size is defined as maxRecordSize plus 2^14,
-     * this is the amount OpenSSL is using.
-     */
-    static final int    maxLargeRecordSize =
-                maxRecordSize   // Max size with a conforming implemenation
-              + maxDataSize;    // extra 2^14 bytes for large data packets.
-
-
-    /*
-     * Maximum record size for alert and change cipher spec records.
-     * They only contain 2 and 1 bytes of data, respectively.
-     * Allocate a smaller array.
-     */
-    static final int    maxAlertRecordSize =
-                                      headerSize        // header
-                                    + maxIVLength       // iv
-                                    + 2                 // alert
-                                    + maxPadding        // padding
-                                    + trailerSize;      // MAC
-
-    /*
-     * The overflow values of integers of 8, 16 and 24 bits.
-     */
-    static final int OVERFLOW_OF_INT08 = (1 << 8);
-    static final int OVERFLOW_OF_INT16 = (1 << 16);
-    static final int OVERFLOW_OF_INT24 = (1 << 24);
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/SSLAlgorithmConstraints.java b/ojluni/src/main/java/sun/security/ssl/SSLAlgorithmConstraints.java
deleted file mode 100755
index 3980705..0000000
--- a/ojluni/src/main/java/sun/security/ssl/SSLAlgorithmConstraints.java
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.security.AlgorithmConstraints;
-import java.security.CryptoPrimitive;
-import java.security.AlgorithmParameters;
-
-import javax.net.ssl.*;
-
-import java.security.Key;
-
-import java.util.Set;
-import java.util.HashSet;
-
-import sun.security.util.DisabledAlgorithmConstraints;
-import sun.security.ssl.CipherSuite.*;
-
-/**
- * Algorithm constraints for disabled algorithms property
- *
- * See the "jdk.certpath.disabledAlgorithms" specification in java.security
- * for the syntax of the disabled algorithm string.
- */
-final class SSLAlgorithmConstraints implements AlgorithmConstraints {
-    private final static AlgorithmConstraints tlsDisabledAlgConstraints =
-            new TLSDisabledAlgConstraints();
-    private final static AlgorithmConstraints x509DisabledAlgConstraints =
-            new X509DisabledAlgConstraints();
-    private AlgorithmConstraints userAlgConstraints = null;
-    private AlgorithmConstraints peerAlgConstraints = null;
-
-    private boolean enabledX509DisabledAlgConstraints = true;
-
-    SSLAlgorithmConstraints(AlgorithmConstraints algorithmConstraints) {
-        userAlgConstraints = algorithmConstraints;
-    }
-
-    SSLAlgorithmConstraints(SSLSocket socket,
-            boolean withDefaultCertPathConstraints) {
-        if (socket != null) {
-            userAlgConstraints =
-                socket.getSSLParameters().getAlgorithmConstraints();
-        }
-
-        if (!withDefaultCertPathConstraints) {
-            enabledX509DisabledAlgConstraints = false;
-        }
-    }
-
-    SSLAlgorithmConstraints(SSLEngine engine,
-            boolean withDefaultCertPathConstraints) {
-        if (engine != null) {
-            userAlgConstraints =
-                engine.getSSLParameters().getAlgorithmConstraints();
-        }
-
-        if (!withDefaultCertPathConstraints) {
-            enabledX509DisabledAlgConstraints = false;
-        }
-    }
-
-    SSLAlgorithmConstraints(SSLSocket socket, String[] supportedAlgorithms,
-            boolean withDefaultCertPathConstraints) {
-        if (socket != null) {
-            userAlgConstraints =
-                socket.getSSLParameters().getAlgorithmConstraints();
-            peerAlgConstraints =
-                new SupportedSignatureAlgorithmConstraints(supportedAlgorithms);
-        }
-
-        if (!withDefaultCertPathConstraints) {
-            enabledX509DisabledAlgConstraints = false;
-        }
-    }
-
-    SSLAlgorithmConstraints(SSLEngine engine, String[] supportedAlgorithms,
-            boolean withDefaultCertPathConstraints) {
-        if (engine != null) {
-            userAlgConstraints =
-                engine.getSSLParameters().getAlgorithmConstraints();
-            peerAlgConstraints =
-                new SupportedSignatureAlgorithmConstraints(supportedAlgorithms);
-        }
-
-        if (!withDefaultCertPathConstraints) {
-            enabledX509DisabledAlgConstraints = false;
-        }
-    }
-
-    public boolean permits(Set<CryptoPrimitive> primitives,
-            String algorithm, AlgorithmParameters parameters) {
-
-        boolean permitted = true;
-
-        if (peerAlgConstraints != null) {
-            permitted = peerAlgConstraints.permits(
-                                    primitives, algorithm, parameters);
-        }
-
-        if (permitted && userAlgConstraints != null) {
-            permitted = userAlgConstraints.permits(
-                                    primitives, algorithm, parameters);
-        }
-
-        if (permitted) {
-            permitted = tlsDisabledAlgConstraints.permits(
-                                    primitives, algorithm, parameters);
-        }
-
-        if (permitted && enabledX509DisabledAlgConstraints) {
-            permitted = x509DisabledAlgConstraints.permits(
-                                    primitives, algorithm, parameters);
-        }
-
-        return permitted;
-    }
-
-    public boolean permits(Set<CryptoPrimitive> primitives, Key key) {
-
-        boolean permitted = true;
-
-        if (peerAlgConstraints != null) {
-            permitted = peerAlgConstraints.permits(primitives, key);
-        }
-
-        if (permitted && userAlgConstraints != null) {
-            permitted = userAlgConstraints.permits(primitives, key);
-        }
-
-        if (permitted) {
-            permitted = tlsDisabledAlgConstraints.permits(primitives, key);
-        }
-
-        if (permitted && enabledX509DisabledAlgConstraints) {
-            permitted = x509DisabledAlgConstraints.permits(primitives, key);
-        }
-
-        return permitted;
-    }
-
-    public boolean permits(Set<CryptoPrimitive> primitives,
-            String algorithm, Key key, AlgorithmParameters parameters) {
-
-        boolean permitted = true;
-
-        if (peerAlgConstraints != null) {
-            permitted = peerAlgConstraints.permits(
-                                    primitives, algorithm, key, parameters);
-        }
-
-        if (permitted && userAlgConstraints != null) {
-            permitted = userAlgConstraints.permits(
-                                    primitives, algorithm, key, parameters);
-        }
-
-        if (permitted) {
-            permitted = tlsDisabledAlgConstraints.permits(
-                                    primitives, algorithm, key, parameters);
-        }
-
-        if (permitted && enabledX509DisabledAlgConstraints) {
-            permitted = x509DisabledAlgConstraints.permits(
-                                    primitives, algorithm, key, parameters);
-        }
-
-        return permitted;
-    }
-
-
-    static private class SupportedSignatureAlgorithmConstraints
-                                    implements AlgorithmConstraints {
-        // supported signature algorithms
-        private String[] supportedAlgorithms;
-
-        SupportedSignatureAlgorithmConstraints(String[] supportedAlgorithms) {
-            if (supportedAlgorithms != null) {
-                this.supportedAlgorithms = supportedAlgorithms.clone();
-            } else {
-                this.supportedAlgorithms = null;
-            }
-        }
-
-        public boolean permits(Set<CryptoPrimitive> primitives,
-                String algorithm, AlgorithmParameters parameters) {
-
-            if (algorithm == null || algorithm.length() == 0) {
-                throw new IllegalArgumentException(
-                        "No algorithm name specified");
-            }
-
-            if (primitives == null || primitives.isEmpty()) {
-                throw new IllegalArgumentException(
-                        "No cryptographic primitive specified");
-            }
-
-            if (supportedAlgorithms == null ||
-                        supportedAlgorithms.length == 0) {
-                return false;
-            }
-
-            // trim the MGF part: <digest>with<encryption>and<mgf>
-            int position = algorithm.indexOf("and");
-            if (position > 0) {
-                algorithm = algorithm.substring(0, position);
-            }
-
-            for (String supportedAlgorithm : supportedAlgorithms) {
-                if (algorithm.equalsIgnoreCase(supportedAlgorithm)) {
-                    return true;
-                }
-            }
-
-            return false;
-        }
-
-        final public boolean permits(Set<CryptoPrimitive> primitives, Key key) {
-            return true;
-        }
-
-        final public boolean permits(Set<CryptoPrimitive> primitives,
-                String algorithm, Key key, AlgorithmParameters parameters) {
-
-            if (algorithm == null || algorithm.length() == 0) {
-                throw new IllegalArgumentException(
-                        "No algorithm name specified");
-            }
-
-            return permits(primitives, algorithm, parameters);
-        }
-    }
-
-    static private class BasicDisabledAlgConstraints
-            extends DisabledAlgorithmConstraints {
-        BasicDisabledAlgConstraints(String propertyName) {
-            super(propertyName);
-        }
-
-        protected Set<String> decomposes(KeyExchange keyExchange,
-                        boolean forCertPathOnly) {
-            Set<String> components = new HashSet<>();
-            switch (keyExchange) {
-                case K_NULL:
-                    if (!forCertPathOnly) {
-                        components.add("NULL");
-                    }
-                    break;
-                case K_RSA:
-                    components.add("RSA");
-                    break;
-                case K_RSA_EXPORT:
-                    components.add("RSA");
-                    components.add("RSA_EXPORT");
-                    break;
-                case K_DH_RSA:
-                    components.add("RSA");
-                    components.add("DH");
-                    components.add("DiffieHellman");
-                    components.add("DH_RSA");
-                    break;
-                case K_DH_DSS:
-                    components.add("DSA");
-                    components.add("DSS");
-                    components.add("DH");
-                    components.add("DiffieHellman");
-                    components.add("DH_DSS");
-                    break;
-                case K_DHE_DSS:
-                    components.add("DSA");
-                    components.add("DSS");
-                    components.add("DH");
-                    components.add("DHE");
-                    components.add("DiffieHellman");
-                    components.add("DHE_DSS");
-                    break;
-                case K_DHE_RSA:
-                    components.add("RSA");
-                    components.add("DH");
-                    components.add("DHE");
-                    components.add("DiffieHellman");
-                    components.add("DHE_RSA");
-                    break;
-                case K_DH_ANON:
-                    if (!forCertPathOnly) {
-                        components.add("ANON");
-                        components.add("DH");
-                        components.add("DiffieHellman");
-                        components.add("DH_ANON");
-                    }
-                    break;
-                case K_ECDH_ECDSA:
-                    components.add("ECDH");
-                    components.add("ECDSA");
-                    components.add("ECDH_ECDSA");
-                    break;
-                case K_ECDH_RSA:
-                    components.add("ECDH");
-                    components.add("RSA");
-                    components.add("ECDH_RSA");
-                    break;
-                case K_ECDHE_ECDSA:
-                    components.add("ECDHE");
-                    components.add("ECDSA");
-                    components.add("ECDHE_ECDSA");
-                    break;
-                case K_ECDHE_RSA:
-                    components.add("ECDHE");
-                    components.add("RSA");
-                    components.add("ECDHE_RSA");
-                    break;
-                case K_ECDH_ANON:
-                    if (!forCertPathOnly) {
-                        components.add("ECDH");
-                        components.add("ANON");
-                        components.add("ECDH_ANON");
-                    }
-                    break;
-                case K_KRB5:
-                    if (!forCertPathOnly) {
-                        components.add("KRB5");
-                    }
-                    break;
-                case K_KRB5_EXPORT:
-                    if (!forCertPathOnly) {
-                        components.add("KRB5_EXPORT");
-                    }
-                    break;
-                default:
-                    // ignore
-            }
-
-            return components;
-        }
-
-        protected Set<String> decomposes(BulkCipher bulkCipher) {
-            Set<String> components = new HashSet<>();
-
-            if (bulkCipher.transformation != null) {
-                components.addAll(super.decomposes(bulkCipher.transformation));
-            }
-
-            return components;
-        }
-
-        protected Set<String> decomposes(MacAlg macAlg) {
-            Set<String> components = new HashSet<>();
-
-            if (macAlg == CipherSuite.M_MD5) {
-                components.add("MD5");
-                components.add("HmacMD5");
-            } else if (macAlg == CipherSuite.M_SHA) {
-                components.add("SHA1");
-                components.add("SHA-1");
-                components.add("HmacSHA1");
-            } else if (macAlg == CipherSuite.M_SHA256) {
-                components.add("SHA256");
-                components.add("SHA-256");
-                components.add("HmacSHA256");
-            } else if (macAlg == CipherSuite.M_SHA384) {
-                components.add("SHA384");
-                components.add("SHA-384");
-                components.add("HmacSHA384");
-            }
-
-            return components;
-        }
-    }
-
-    static private class TLSDisabledAlgConstraints
-            extends BasicDisabledAlgConstraints {
-
-        TLSDisabledAlgConstraints() {
-            super(DisabledAlgorithmConstraints.PROPERTY_TLS_DISABLED_ALGS);
-        }
-
-        @Override
-        protected Set<String> decomposes(String algorithm) {
-            if (algorithm.startsWith("SSL_") || algorithm.startsWith("TLS_")) {
-                CipherSuite cipherSuite = null;
-                try {
-                    cipherSuite = CipherSuite.valueOf(algorithm);
-                } catch (IllegalArgumentException iae) {
-                    // ignore: unknown or unsupported ciphersuite
-                }
-
-                if (cipherSuite != null) {
-                    Set<String> components = new HashSet<>();
-
-                    if(cipherSuite.keyExchange != null) {
-                        components.addAll(
-                            decomposes(cipherSuite.keyExchange, false));
-                    }
-
-                    if (cipherSuite.cipher != null) {
-                        components.addAll(decomposes(cipherSuite.cipher));
-                    }
-
-                    if (cipherSuite.macAlg != null) {
-                        components.addAll(decomposes(cipherSuite.macAlg));
-                    }
-
-                    return components;
-                }
-            }
-
-            return super.decomposes(algorithm);
-        }
-    }
-
-    static private class X509DisabledAlgConstraints
-            extends BasicDisabledAlgConstraints {
-
-        X509DisabledAlgConstraints() {
-            super(DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
-        }
-
-        @Override
-        protected Set<String> decomposes(String algorithm) {
-            if (algorithm.startsWith("SSL_") || algorithm.startsWith("TLS_")) {
-                CipherSuite cipherSuite = null;
-                try {
-                    cipherSuite = CipherSuite.valueOf(algorithm);
-                } catch (IllegalArgumentException iae) {
-                    // ignore: unknown or unsupported ciphersuite
-                }
-
-                if (cipherSuite != null) {
-                    Set<String> components = new HashSet<>();
-
-                    if(cipherSuite.keyExchange != null) {
-                        components.addAll(
-                            decomposes(cipherSuite.keyExchange, true));
-                    }
-
-                    // Certification path algorithm constraints do not apply
-                    // to cipherSuite.cipher and cipherSuite.macAlg.
-
-                    return components;
-                }
-            }
-
-            return super.decomposes(algorithm);
-        }
-    }
-}
-
diff --git a/ojluni/src/main/java/sun/security/ssl/SSLContextImpl.java b/ojluni/src/main/java/sun/security/ssl/SSLContextImpl.java
deleted file mode 100755
index c2081b7..0000000
--- a/ojluni/src/main/java/sun/security/ssl/SSLContextImpl.java
+++ /dev/null
@@ -1,1162 +0,0 @@
-/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.net.Socket;
-
-import java.io.*;
-import java.util.*;
-import java.security.*;
-import java.security.cert.*;
-import java.security.cert.Certificate;
-
-import javax.net.ssl.*;
-
-import sun.security.provider.certpath.AlgorithmChecker;
-
-public abstract class SSLContextImpl extends SSLContextSpi {
-
-    private static final Debug debug = Debug.getInstance("ssl");
-
-    private final EphemeralKeyManager ephemeralKeyManager;
-    private final SSLSessionContextImpl clientCache;
-    private final SSLSessionContextImpl serverCache;
-
-    private boolean isInitialized;
-
-    private X509ExtendedKeyManager keyManager;
-    private X509TrustManager trustManager;
-    private SecureRandom secureRandom;
-
-    // The default algrithm constraints
-    private AlgorithmConstraints defaultAlgorithmConstraints =
-                                 new SSLAlgorithmConstraints(null);
-
-    // supported and default protocols
-    private ProtocolList defaultServerProtocolList;
-    private ProtocolList defaultClientProtocolList;
-    private ProtocolList supportedProtocolList;
-
-    // supported and default cipher suites
-    private CipherSuiteList defaultServerCipherSuiteList;
-    private CipherSuiteList defaultClientCipherSuiteList;
-    private CipherSuiteList supportedCipherSuiteList;
-
-    SSLContextImpl() {
-        ephemeralKeyManager = new EphemeralKeyManager();
-        clientCache = new SSLSessionContextImpl();
-        serverCache = new SSLSessionContextImpl();
-    }
-
-    protected void engineInit(KeyManager[] km, TrustManager[] tm,
-                                SecureRandom sr) throws KeyManagementException {
-        isInitialized = false;
-        keyManager = chooseKeyManager(km);
-
-        if (tm == null) {
-            try {
-                TrustManagerFactory tmf = TrustManagerFactory.getInstance(
-                        TrustManagerFactory.getDefaultAlgorithm());
-                tmf.init((KeyStore)null);
-                tm = tmf.getTrustManagers();
-            } catch (Exception e) {
-                // eat
-            }
-        }
-        trustManager = chooseTrustManager(tm);
-
-        if (sr == null) {
-            secureRandom = JsseJce.getSecureRandom();
-        } else {
-            if (SunJSSE.isFIPS() &&
-                        (sr.getProvider() != SunJSSE.cryptoProvider)) {
-                throw new KeyManagementException
-                    ("FIPS mode: SecureRandom must be from provider "
-                    + SunJSSE.cryptoProvider.getName());
-            }
-            secureRandom = sr;
-        }
-
-        /*
-         * The initial delay of seeding the random number generator
-         * could be long enough to cause the initial handshake on our
-         * first connection to timeout and fail. Make sure it is
-         * primed and ready by getting some initial output from it.
-         */
-        if (debug != null && Debug.isOn("sslctx")) {
-            System.out.println("trigger seeding of SecureRandom");
-        }
-        secureRandom.nextInt();
-        if (debug != null && Debug.isOn("sslctx")) {
-            System.out.println("done seeding SecureRandom");
-        }
-        isInitialized = true;
-    }
-
-    private X509TrustManager chooseTrustManager(TrustManager[] tm)
-            throws KeyManagementException {
-        // We only use the first instance of X509TrustManager passed to us.
-        for (int i = 0; tm != null && i < tm.length; i++) {
-            if (tm[i] instanceof X509TrustManager) {
-                if (SunJSSE.isFIPS() &&
-                        !(tm[i] instanceof X509TrustManagerImpl)) {
-                    throw new KeyManagementException
-                        ("FIPS mode: only SunJSSE TrustManagers may be used");
-                }
-
-                if (tm[i] instanceof X509ExtendedTrustManager) {
-                    return (X509TrustManager)tm[i];
-                } else {
-                    return new AbstractTrustManagerWrapper(
-                                        (X509TrustManager)tm[i]);
-                }
-            }
-        }
-
-        // nothing found, return a dummy X509TrustManager.
-        return DummyX509TrustManager.INSTANCE;
-    }
-
-    private X509ExtendedKeyManager chooseKeyManager(KeyManager[] kms)
-            throws KeyManagementException {
-        for (int i = 0; kms != null && i < kms.length; i++) {
-            KeyManager km = kms[i];
-            if (!(km instanceof X509KeyManager)) {
-                continue;
-            }
-            if (SunJSSE.isFIPS()) {
-                // In FIPS mode, require that one of SunJSSE's own keymanagers
-                // is used. Otherwise, we cannot be sure that only keys from
-                // the FIPS token are used.
-                if ((km instanceof X509KeyManagerImpl)
-                            || (km instanceof SunX509KeyManagerImpl)) {
-                    return (X509ExtendedKeyManager)km;
-                } else {
-                    // throw exception, we don't want to silently use the
-                    // dummy keymanager without telling the user.
-                    throw new KeyManagementException
-                        ("FIPS mode: only SunJSSE KeyManagers may be used");
-                }
-            }
-            if (km instanceof X509ExtendedKeyManager) {
-                return (X509ExtendedKeyManager)km;
-            }
-            if (debug != null && Debug.isOn("sslctx")) {
-                System.out.println(
-                    "X509KeyManager passed to " +
-                    "SSLContext.init():  need an " +
-                    "X509ExtendedKeyManager for SSLEngine use");
-            }
-            return new AbstractKeyManagerWrapper((X509KeyManager)km);
-        }
-
-        // nothing found, return a dummy X509ExtendedKeyManager
-        return DummyX509KeyManager.INSTANCE;
-    }
-
-    protected SSLSocketFactory engineGetSocketFactory() {
-        if (!isInitialized) {
-            throw new IllegalStateException(
-                "SSLContextImpl is not initialized");
-        }
-       return new SSLSocketFactoryImpl(this);
-    }
-
-    protected SSLServerSocketFactory engineGetServerSocketFactory() {
-        if (!isInitialized) {
-            throw new IllegalStateException("SSLContext is not initialized");
-        }
-        return new SSLServerSocketFactoryImpl(this);
-    }
-
-    protected SSLEngine engineCreateSSLEngine() {
-        if (!isInitialized) {
-            throw new IllegalStateException(
-                "SSLContextImpl is not initialized");
-        }
-        return new SSLEngineImpl(this);
-    }
-
-    protected SSLEngine engineCreateSSLEngine(String host, int port) {
-        if (!isInitialized) {
-            throw new IllegalStateException(
-                "SSLContextImpl is not initialized");
-        }
-        return new SSLEngineImpl(this, host, port);
-    }
-
-    protected SSLSessionContext engineGetClientSessionContext() {
-        return clientCache;
-    }
-
-    protected SSLSessionContext engineGetServerSessionContext() {
-        return serverCache;
-    }
-
-    SecureRandom getSecureRandom() {
-        return secureRandom;
-    }
-
-    X509ExtendedKeyManager getX509KeyManager() {
-        return keyManager;
-    }
-
-    X509TrustManager getX509TrustManager() {
-        return trustManager;
-    }
-
-    EphemeralKeyManager getEphemeralKeyManager() {
-        return ephemeralKeyManager;
-    }
-
-    abstract SSLParameters getDefaultServerSSLParams();
-    abstract SSLParameters getDefaultClientSSLParams();
-    abstract SSLParameters getSupportedSSLParams();
-
-    // Get suported ProtoclList.
-    ProtocolList getSuportedProtocolList() {
-        if (supportedProtocolList == null) {
-            supportedProtocolList =
-                new ProtocolList(getSupportedSSLParams().getProtocols());
-        }
-
-        return supportedProtocolList;
-    }
-
-    // Get default ProtoclList.
-    ProtocolList getDefaultProtocolList(boolean roleIsServer) {
-        if (roleIsServer) {
-            if (defaultServerProtocolList == null) {
-                defaultServerProtocolList = new ProtocolList(
-                        getDefaultServerSSLParams().getProtocols());
-            }
-
-            return defaultServerProtocolList;
-        } else {
-            if (defaultClientProtocolList == null) {
-                defaultClientProtocolList = new ProtocolList(
-                        getDefaultClientSSLParams().getProtocols());
-            }
-
-            return defaultClientProtocolList;
-        }
-    }
-
-    // Get suported CipherSuiteList.
-    CipherSuiteList getSupportedCipherSuiteList() {
-        // The maintenance of cipher suites needs to be synchronized.
-        synchronized (this) {
-            // Clear cache of available ciphersuites.
-            clearAvailableCache();
-
-            if (supportedCipherSuiteList == null) {
-                supportedCipherSuiteList = getApplicableCipherSuiteList(
-                        getSuportedProtocolList(), false);
-            }
-
-            return supportedCipherSuiteList;
-        }
-    }
-
-    // Get default CipherSuiteList.
-    CipherSuiteList getDefaultCipherSuiteList(boolean roleIsServer) {
-        // The maintenance of cipher suites needs to be synchronized.
-        synchronized (this) {
-            // Clear cache of available ciphersuites.
-            clearAvailableCache();
-
-            if (roleIsServer) {
-                if (defaultServerCipherSuiteList == null) {
-                    defaultServerCipherSuiteList = getApplicableCipherSuiteList(
-                        getDefaultProtocolList(true), true);
-                }
-
-                return defaultServerCipherSuiteList;
-            } else {
-                if (defaultClientCipherSuiteList == null) {
-                    defaultClientCipherSuiteList = getApplicableCipherSuiteList(
-                        getDefaultProtocolList(false), true);
-                }
-
-                return defaultClientCipherSuiteList;
-            }
-        }
-    }
-
-    /**
-     * Return whether a protocol list is the original default enabled
-     * protocols.  See: SSLSocket/SSLEngine.setEnabledProtocols()
-     */
-    boolean isDefaultProtocolList(ProtocolList protocols) {
-        return (protocols == defaultServerProtocolList) ||
-               (protocols == defaultClientProtocolList);
-    }
-
-
-    /*
-     * Return the list of all available CipherSuites with a priority of
-     * minPriority or above.
-     */
-    private CipherSuiteList getApplicableCipherSuiteList(
-            ProtocolList protocols, boolean onlyEnabled) {
-
-        int minPriority = CipherSuite.SUPPORTED_SUITES_PRIORITY;
-        if (onlyEnabled) {
-            minPriority = CipherSuite.DEFAULT_SUITES_PRIORITY;
-        }
-
-        Collection<CipherSuite> allowedCipherSuites =
-                                    CipherSuite.allowedCipherSuites();
-
-        TreeSet<CipherSuite> suites = new TreeSet<>();
-        if (!(protocols.collection().isEmpty()) &&
-                protocols.min.v != ProtocolVersion.NONE.v) {
-            for (CipherSuite suite : allowedCipherSuites) {
-                if (!suite.allowed || suite.priority < minPriority) {
-                    continue;
-                }
-
-                if (suite.isAvailable() &&
-                        suite.obsoleted > protocols.min.v &&
-                        suite.supported <= protocols.max.v) {
-                    if (defaultAlgorithmConstraints.permits(
-                            EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
-                            suite.name, null)) {
-                        suites.add(suite);
-                    }
-                } else if (debug != null &&
-                        Debug.isOn("sslctx") && Debug.isOn("verbose")) {
-                    if (suite.obsoleted <= protocols.min.v) {
-                        System.out.println(
-                            "Ignoring obsoleted cipher suite: " + suite);
-                    } else if (suite.supported > protocols.max.v) {
-                        System.out.println(
-                            "Ignoring unsupported cipher suite: " + suite);
-                    } else {
-                        System.out.println(
-                            "Ignoring unavailable cipher suite: " + suite);
-                    }
-                }
-            }
-        }
-
-        return new CipherSuiteList(suites);
-    }
-
-    /**
-     * Clear cache of available ciphersuites. If we support all ciphers
-     * internally, there is no need to clear the cache and calling this
-     * method has no effect.
-     *
-     * Note that every call to clearAvailableCache() and the maintenance of
-     * cipher suites need to be synchronized with this instance.
-     */
-    private void clearAvailableCache() {
-        if (CipherSuite.DYNAMIC_AVAILABILITY) {
-            supportedCipherSuiteList = null;
-            defaultServerCipherSuiteList = null;
-            defaultClientCipherSuiteList = null;
-            CipherSuite.BulkCipher.clearAvailableCache();
-            JsseJce.clearEcAvailable();
-        }
-    }
-
-    /*
-     * The SSLContext implementation for TLS/SSL algorithm
-     *
-     * SSL/TLS protocols specify the forward compatibility and version
-     * roll-back attack protections, however, a number of SSL/TLS server
-     * vendors did not implement these aspects properly, and some current
-     * SSL/TLS servers may refuse to talk to a TLS 1.1 or later client.
-     *
-     * Considering above interoperability issues, SunJSSE will not set
-     * TLS 1.1 and TLS 1.2 as the enabled protocols for client by default.
-     *
-     * For SSL/TLS servers, there is no such interoperability issues as
-     * SSL/TLS clients. In SunJSSE, TLS 1.1 or later version will be the
-     * enabled protocols for server by default.
-     *
-     * We may change the behavior when popular TLS/SSL vendors support TLS
-     * forward compatibility properly.
-     *
-     * SSLv2Hello is no longer necessary.  This interoperability option was
-     * put in place in the late 90's when SSLv3/TLS1.0 were relatively new
-     * and there were a fair number of SSLv2-only servers deployed.  Because
-     * of the security issues in SSLv2, it is rarely (if ever) used, as
-     * deployments should now be using SSLv3 and TLSv1.
-     *
-     * Considering the issues of SSLv2Hello, we should not enable SSLv2Hello
-     * by default. Applications still can use it by enabling SSLv2Hello with
-     * the series of setEnabledProtocols APIs.
-     */
-
-    /*
-     * The conservative SSLContext implementation for TLS, SSL, SSLv3 and
-     * TLS10 algorithm.
-     *
-     * This is a super class of DefaultSSLContext and TLS10Context.
-     *
-     * @see SSLContext
-     */
-    private static class ConservativeSSLContext extends SSLContextImpl {
-        // parameters
-        private static SSLParameters defaultServerSSLParams;
-        private static SSLParameters defaultClientSSLParams;
-        private static SSLParameters supportedSSLParams;
-
-        static {
-            if (SunJSSE.isFIPS()) {
-                supportedSSLParams = new SSLParameters();
-                supportedSSLParams.setProtocols(new String[] {
-                    ProtocolVersion.TLS10.name,
-                    ProtocolVersion.TLS11.name,
-                    ProtocolVersion.TLS12.name
-                });
-
-                defaultServerSSLParams = supportedSSLParams;
-
-                defaultClientSSLParams = new SSLParameters();
-                defaultClientSSLParams.setProtocols(new String[] {
-                    ProtocolVersion.TLS10.name
-                });
-
-            } else {
-                supportedSSLParams = new SSLParameters();
-                supportedSSLParams.setProtocols(new String[] {
-                    ProtocolVersion.SSL20Hello.name,
-                    ProtocolVersion.SSL30.name,
-                    ProtocolVersion.TLS10.name,
-                    ProtocolVersion.TLS11.name,
-                    ProtocolVersion.TLS12.name
-                });
-
-                defaultServerSSLParams = supportedSSLParams;
-
-                defaultClientSSLParams = new SSLParameters();
-                defaultClientSSLParams.setProtocols(new String[] {
-                    ProtocolVersion.SSL30.name,
-                    ProtocolVersion.TLS10.name
-                });
-            }
-        }
-
-        SSLParameters getDefaultServerSSLParams() {
-            return defaultServerSSLParams;
-        }
-
-        SSLParameters getDefaultClientSSLParams() {
-            return defaultClientSSLParams;
-        }
-
-        SSLParameters getSupportedSSLParams() {
-            return supportedSSLParams;
-        }
-    }
-
-    /*
-     * The SSLContext implementation for default algorithm
-     *
-     * @see SSLContext
-     */
-    public static final class DefaultSSLContext extends ConservativeSSLContext {
-        private static final String NONE = "NONE";
-        private static final String P11KEYSTORE = "PKCS11";
-
-        private static volatile SSLContextImpl defaultImpl;
-
-        private static TrustManager[] defaultTrustManagers;
-        private static KeyManager[] defaultKeyManagers;
-
-        public DefaultSSLContext() throws Exception {
-            try {
-                super.engineInit(getDefaultKeyManager(),
-                        getDefaultTrustManager(), null);
-            } catch (Exception e) {
-                if (debug != null && Debug.isOn("defaultctx")) {
-                    System.out.println("default context init failed: " + e);
-                }
-                throw e;
-            }
-
-            if (defaultImpl == null) {
-                defaultImpl = this;
-            }
-        }
-
-        protected void engineInit(KeyManager[] km, TrustManager[] tm,
-            SecureRandom sr) throws KeyManagementException {
-            throw new KeyManagementException
-                ("Default SSLContext is initialized automatically");
-        }
-
-        static synchronized SSLContextImpl getDefaultImpl() throws Exception {
-            if (defaultImpl == null) {
-                new DefaultSSLContext();
-            }
-            return defaultImpl;
-        }
-
-        private static synchronized TrustManager[] getDefaultTrustManager()
-                throws Exception {
-            if (defaultTrustManagers != null) {
-                return defaultTrustManagers;
-            }
-
-            KeyStore ks =
-                TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx");
-
-            TrustManagerFactory tmf = TrustManagerFactory.getInstance(
-                TrustManagerFactory.getDefaultAlgorithm());
-            tmf.init(ks);
-            defaultTrustManagers = tmf.getTrustManagers();
-            return defaultTrustManagers;
-        }
-
-        private static synchronized KeyManager[] getDefaultKeyManager()
-                throws Exception {
-            if (defaultKeyManagers != null) {
-                return defaultKeyManagers;
-            }
-
-            final Map<String,String> props = new HashMap<>();
-            AccessController.doPrivileged(
-                        new PrivilegedExceptionAction<Object>() {
-                public Object run() throws Exception {
-                    props.put("keyStore",  System.getProperty(
-                                "javax.net.ssl.keyStore", ""));
-                    props.put("keyStoreType", System.getProperty(
-                                "javax.net.ssl.keyStoreType",
-                                KeyStore.getDefaultType()));
-                    props.put("keyStoreProvider", System.getProperty(
-                                "javax.net.ssl.keyStoreProvider", ""));
-                    props.put("keyStorePasswd", System.getProperty(
-                                "javax.net.ssl.keyStorePassword", ""));
-                    return null;
-                }
-            });
-
-            final String defaultKeyStore = props.get("keyStore");
-            String defaultKeyStoreType = props.get("keyStoreType");
-            String defaultKeyStoreProvider = props.get("keyStoreProvider");
-            if (debug != null && Debug.isOn("defaultctx")) {
-                System.out.println("keyStore is : " + defaultKeyStore);
-                System.out.println("keyStore type is : " +
-                                        defaultKeyStoreType);
-                System.out.println("keyStore provider is : " +
-                                        defaultKeyStoreProvider);
-            }
-
-            if (P11KEYSTORE.equals(defaultKeyStoreType) &&
-                    !NONE.equals(defaultKeyStore)) {
-                throw new IllegalArgumentException("if keyStoreType is "
-                    + P11KEYSTORE + ", then keyStore must be " + NONE);
-            }
-
-            FileInputStream fs = null;
-            if (defaultKeyStore.length() != 0 && !NONE.equals(defaultKeyStore)) {
-                fs = AccessController.doPrivileged(
-                        new PrivilegedExceptionAction<FileInputStream>() {
-                    public FileInputStream run() throws Exception {
-                        return new FileInputStream(defaultKeyStore);
-                    }
-                });
-            }
-
-            String defaultKeyStorePassword = props.get("keyStorePasswd");
-            char[] passwd = null;
-            if (defaultKeyStorePassword.length() != 0) {
-                passwd = defaultKeyStorePassword.toCharArray();
-            }
-
-            /**
-             * Try to initialize key store.
-             */
-            KeyStore ks = null;
-            if ((defaultKeyStoreType.length()) != 0) {
-                if (debug != null && Debug.isOn("defaultctx")) {
-                    System.out.println("init keystore");
-                }
-                if (defaultKeyStoreProvider.length() == 0) {
-                    ks = KeyStore.getInstance(defaultKeyStoreType);
-                } else {
-                    ks = KeyStore.getInstance(defaultKeyStoreType,
-                                        defaultKeyStoreProvider);
-                }
-
-                // if defaultKeyStore is NONE, fs will be null
-                ks.load(fs, passwd);
-            }
-            if (fs != null) {
-                fs.close();
-                fs = null;
-            }
-
-            /*
-             * Try to initialize key manager.
-             */
-            if (debug != null && Debug.isOn("defaultctx")) {
-                System.out.println("init keymanager of type " +
-                    KeyManagerFactory.getDefaultAlgorithm());
-            }
-            KeyManagerFactory kmf = KeyManagerFactory.getInstance(
-                KeyManagerFactory.getDefaultAlgorithm());
-
-            if (P11KEYSTORE.equals(defaultKeyStoreType)) {
-                kmf.init(ks, null); // do not pass key passwd if using token
-            } else {
-                kmf.init(ks, passwd);
-            }
-
-            defaultKeyManagers = kmf.getKeyManagers();
-            return defaultKeyManagers;
-        }
-    }
-
-    /*
-     * The SSLContext implementation for TLS, SSL, SSLv3 and TLS10 algorithm
-     *
-     * @see SSLContext
-     */
-    public static final class TLS10Context extends ConservativeSSLContext {
-        // use the default constructor and methods
-    }
-
-    /*
-     * The SSLContext implementation for TLS11 algorithm
-     *
-     * @see SSLContext
-     */
-    public static final class TLS11Context extends SSLContextImpl {
-        // parameters
-        private static SSLParameters defaultServerSSLParams;
-        private static SSLParameters defaultClientSSLParams;
-        private static SSLParameters supportedSSLParams;
-
-        static {
-            if (SunJSSE.isFIPS()) {
-                supportedSSLParams = new SSLParameters();
-                supportedSSLParams.setProtocols(new String[] {
-                    ProtocolVersion.TLS10.name,
-                    ProtocolVersion.TLS11.name,
-                    ProtocolVersion.TLS12.name
-                });
-
-                defaultServerSSLParams = supportedSSLParams;
-
-                defaultClientSSLParams = new SSLParameters();
-                defaultClientSSLParams.setProtocols(new String[] {
-                    ProtocolVersion.TLS10.name,
-                    ProtocolVersion.TLS11.name
-                });
-
-            } else {
-                supportedSSLParams = new SSLParameters();
-                supportedSSLParams.setProtocols(new String[] {
-                    ProtocolVersion.SSL20Hello.name,
-                    ProtocolVersion.SSL30.name,
-                    ProtocolVersion.TLS10.name,
-                    ProtocolVersion.TLS11.name,
-                    ProtocolVersion.TLS12.name
-                });
-
-                defaultServerSSLParams = supportedSSLParams;
-
-                defaultClientSSLParams = new SSLParameters();
-                defaultClientSSLParams.setProtocols(new String[] {
-                    ProtocolVersion.SSL30.name,
-                    ProtocolVersion.TLS10.name,
-                    ProtocolVersion.TLS11.name
-                });
-            }
-        }
-
-        SSLParameters getDefaultServerSSLParams() {
-            return defaultServerSSLParams;
-        }
-
-        SSLParameters getDefaultClientSSLParams() {
-            return defaultClientSSLParams;
-        }
-
-        SSLParameters getSupportedSSLParams() {
-            return supportedSSLParams;
-        }
-    }
-
-    /*
-     * The SSLContext implementation for TLS12 algorithm
-     *
-     * @see SSLContext
-     */
-    public static final class TLS12Context extends SSLContextImpl {
-        // parameters
-        private static SSLParameters defaultServerSSLParams;
-        private static SSLParameters defaultClientSSLParams;
-        private static SSLParameters supportedSSLParams;
-
-        static {
-            if (SunJSSE.isFIPS()) {
-                supportedSSLParams = new SSLParameters();
-                supportedSSLParams.setProtocols(new String[] {
-                    ProtocolVersion.TLS10.name,
-                    ProtocolVersion.TLS11.name,
-                    ProtocolVersion.TLS12.name
-                });
-
-                defaultServerSSLParams = supportedSSLParams;
-
-                defaultClientSSLParams = new SSLParameters();
-                defaultClientSSLParams.setProtocols(new String[] {
-                    ProtocolVersion.TLS10.name,
-                    ProtocolVersion.TLS11.name,
-                    ProtocolVersion.TLS12.name
-                });
-
-            } else {
-                supportedSSLParams = new SSLParameters();
-                supportedSSLParams.setProtocols(new String[] {
-                    ProtocolVersion.SSL20Hello.name,
-                    ProtocolVersion.SSL30.name,
-                    ProtocolVersion.TLS10.name,
-                    ProtocolVersion.TLS11.name,
-                    ProtocolVersion.TLS12.name
-                });
-
-                defaultServerSSLParams = supportedSSLParams;
-
-                defaultClientSSLParams = new SSLParameters();
-                defaultClientSSLParams.setProtocols(new String[] {
-                    ProtocolVersion.SSL30.name,
-                    ProtocolVersion.TLS10.name,
-                    ProtocolVersion.TLS11.name,
-                    ProtocolVersion.TLS12.name
-                });
-            }
-        }
-
-        SSLParameters getDefaultServerSSLParams() {
-            return defaultServerSSLParams;
-        }
-
-        SSLParameters getDefaultClientSSLParams() {
-            return defaultClientSSLParams;
-        }
-
-        SSLParameters getSupportedSSLParams() {
-            return supportedSSLParams;
-        }
-    }
-
-}
-
-
-final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
-            implements X509TrustManager {
-
-    // the delegated trust manager
-    private final X509TrustManager tm;
-
-    AbstractTrustManagerWrapper(X509TrustManager tm) {
-        this.tm = tm;
-    }
-
-    @Override
-    public void checkClientTrusted(X509Certificate[] chain, String authType)
-        throws CertificateException {
-        tm.checkClientTrusted(chain, authType);
-    }
-
-    @Override
-    public void checkServerTrusted(X509Certificate[] chain, String authType)
-        throws CertificateException {
-        tm.checkServerTrusted(chain, authType);
-    }
-
-    @Override
-    public X509Certificate[] getAcceptedIssuers() {
-        return tm.getAcceptedIssuers();
-    }
-
-    @Override
-    public void checkClientTrusted(X509Certificate[] chain, String authType,
-                Socket socket) throws CertificateException {
-        tm.checkClientTrusted(chain, authType);
-        checkAdditionalTrust(chain, authType, socket, true);
-    }
-
-    @Override
-    public void checkServerTrusted(X509Certificate[] chain, String authType,
-            Socket socket) throws CertificateException {
-        tm.checkServerTrusted(chain, authType);
-        checkAdditionalTrust(chain, authType, socket, false);
-    }
-
-    @Override
-    public void checkClientTrusted(X509Certificate[] chain, String authType,
-            SSLEngine engine) throws CertificateException {
-        tm.checkClientTrusted(chain, authType);
-        checkAdditionalTrust(chain, authType, engine, true);
-    }
-
-    @Override
-    public void checkServerTrusted(X509Certificate[] chain, String authType,
-            SSLEngine engine) throws CertificateException {
-        tm.checkServerTrusted(chain, authType);
-        checkAdditionalTrust(chain, authType, engine, false);
-    }
-
-    private void checkAdditionalTrust(X509Certificate[] chain, String authType,
-                Socket socket, boolean isClient) throws CertificateException {
-        if (socket != null && socket.isConnected() &&
-                                    socket instanceof SSLSocket) {
-
-            SSLSocket sslSocket = (SSLSocket)socket;
-            SSLSession session = sslSocket.getHandshakeSession();
-            if (session == null) {
-                throw new CertificateException("No handshake session");
-            }
-
-            // check endpoint identity
-            String identityAlg = sslSocket.getSSLParameters().
-                                        getEndpointIdentificationAlgorithm();
-            if (identityAlg != null && identityAlg.length() != 0) {
-                String hostname = session.getPeerHost();
-                X509TrustManagerImpl.checkIdentity(
-                                    hostname, chain[0], identityAlg);
-            }
-
-            // try the best to check the algorithm constraints
-            ProtocolVersion protocolVersion =
-                ProtocolVersion.valueOf(session.getProtocol());
-            AlgorithmConstraints constraints = null;
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                if (session instanceof ExtendedSSLSession) {
-                    ExtendedSSLSession extSession =
-                                    (ExtendedSSLSession)session;
-                    String[] peerSupportedSignAlgs =
-                            extSession.getLocalSupportedSignatureAlgorithms();
-
-                    constraints = new SSLAlgorithmConstraints(
-                                    sslSocket, peerSupportedSignAlgs, true);
-                } else {
-                    constraints =
-                            new SSLAlgorithmConstraints(sslSocket, true);
-                }
-            } else {
-                constraints = new SSLAlgorithmConstraints(sslSocket, true);
-            }
-
-            checkAlgorithmConstraints(chain, constraints);
-        }
-    }
-
-    private void checkAdditionalTrust(X509Certificate[] chain, String authType,
-            SSLEngine engine, boolean isClient) throws CertificateException {
-        if (engine != null) {
-            SSLSession session = engine.getHandshakeSession();
-            if (session == null) {
-                throw new CertificateException("No handshake session");
-            }
-
-            // check endpoint identity
-            String identityAlg = engine.getSSLParameters().
-                                        getEndpointIdentificationAlgorithm();
-            if (identityAlg != null && identityAlg.length() != 0) {
-                String hostname = session.getPeerHost();
-                X509TrustManagerImpl.checkIdentity(
-                                    hostname, chain[0], identityAlg);
-            }
-
-            // try the best to check the algorithm constraints
-            ProtocolVersion protocolVersion =
-                ProtocolVersion.valueOf(session.getProtocol());
-            AlgorithmConstraints constraints = null;
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                if (session instanceof ExtendedSSLSession) {
-                    ExtendedSSLSession extSession =
-                                    (ExtendedSSLSession)session;
-                    String[] peerSupportedSignAlgs =
-                            extSession.getLocalSupportedSignatureAlgorithms();
-
-                    constraints = new SSLAlgorithmConstraints(
-                                    engine, peerSupportedSignAlgs, true);
-                } else {
-                    constraints =
-                            new SSLAlgorithmConstraints(engine, true);
-                }
-            } else {
-                constraints = new SSLAlgorithmConstraints(engine, true);
-            }
-
-            checkAlgorithmConstraints(chain, constraints);
-        }
-    }
-
-    private void checkAlgorithmConstraints(X509Certificate[] chain,
-            AlgorithmConstraints constraints) throws CertificateException {
-
-        try {
-            // Does the certificate chain end with a trusted certificate?
-            int checkedLength = chain.length - 1;
-
-            Collection<X509Certificate> trustedCerts = new HashSet<>();
-            X509Certificate[] certs = tm.getAcceptedIssuers();
-            if ((certs != null) && (certs.length > 0)){
-                Collections.addAll(trustedCerts, certs);
-            }
-
-            if (trustedCerts.contains(chain[checkedLength])) {
-                    checkedLength--;
-            }
-
-            // A forward checker, need to check from trust to target
-            if (checkedLength >= 0) {
-                AlgorithmChecker checker = new AlgorithmChecker(constraints);
-                checker.init(false);
-                for (int i = checkedLength; i >= 0; i--) {
-                    Certificate cert = chain[i];
-                    // We don't care about the unresolved critical extensions.
-                    checker.check(cert, Collections.<String>emptySet());
-                }
-            }
-        } catch (CertPathValidatorException cpve) {
-            throw new CertificateException(
-                "Certificates does not conform to algorithm constraints");
-        }
-    }
-}
-
-// Dummy X509TrustManager implementation, rejects all peer certificates.
-// Used if the application did not specify a proper X509TrustManager.
-final class DummyX509TrustManager extends X509ExtendedTrustManager
-            implements X509TrustManager {
-
-    static final X509TrustManager INSTANCE = new DummyX509TrustManager();
-
-    private DummyX509TrustManager() {
-        // empty
-    }
-
-    /*
-     * Given the partial or complete certificate chain
-     * provided by the peer, build a certificate path
-     * to a trusted root and return if it can be
-     * validated and is trusted for client SSL authentication.
-     * If not, it throws an exception.
-     */
-    @Override
-    public void checkClientTrusted(X509Certificate[] chain, String authType)
-        throws CertificateException {
-        throw new CertificateException(
-            "No X509TrustManager implementation avaiable");
-    }
-
-    /*
-     * Given the partial or complete certificate chain
-     * provided by the peer, build a certificate path
-     * to a trusted root and return if it can be
-     * validated and is trusted for server SSL authentication.
-     * If not, it throws an exception.
-     */
-    @Override
-    public void checkServerTrusted(X509Certificate[] chain, String authType)
-        throws CertificateException {
-        throw new CertificateException(
-            "No X509TrustManager implementation available");
-    }
-
-    /*
-     * Return an array of issuer certificates which are trusted
-     * for authenticating peers.
-     */
-    @Override
-    public X509Certificate[] getAcceptedIssuers() {
-        return new X509Certificate[0];
-    }
-
-    @Override
-    public void checkClientTrusted(X509Certificate[] chain, String authType,
-                Socket socket) throws CertificateException {
-        throw new CertificateException(
-            "No X509TrustManager implementation available");
-    }
-
-    @Override
-    public void checkServerTrusted(X509Certificate[] chain, String authType,
-            Socket socket) throws CertificateException {
-        throw new CertificateException(
-            "No X509TrustManager implementation available");
-    }
-
-    @Override
-    public void checkClientTrusted(X509Certificate[] chain, String authType,
-            SSLEngine engine) throws CertificateException {
-        throw new CertificateException(
-            "No X509TrustManager implementation available");
-    }
-
-    @Override
-    public void checkServerTrusted(X509Certificate[] chain, String authType,
-            SSLEngine engine) throws CertificateException {
-        throw new CertificateException(
-            "No X509TrustManager implementation available");
-    }
-}
-
-/*
- * A wrapper class to turn a X509KeyManager into an X509ExtendedKeyManager
- */
-final class AbstractKeyManagerWrapper extends X509ExtendedKeyManager {
-
-    private final X509KeyManager km;
-
-    AbstractKeyManagerWrapper(X509KeyManager km) {
-        this.km = km;
-    }
-
-    public String[] getClientAliases(String keyType, Principal[] issuers) {
-        return km.getClientAliases(keyType, issuers);
-    }
-
-    public String chooseClientAlias(String[] keyType, Principal[] issuers,
-            Socket socket) {
-        return km.chooseClientAlias(keyType, issuers, socket);
-    }
-
-    public String[] getServerAliases(String keyType, Principal[] issuers) {
-        return km.getServerAliases(keyType, issuers);
-    }
-
-    public String chooseServerAlias(String keyType, Principal[] issuers,
-            Socket socket) {
-        return km.chooseServerAlias(keyType, issuers, socket);
-    }
-
-    public X509Certificate[] getCertificateChain(String alias) {
-        return km.getCertificateChain(alias);
-    }
-
-    public PrivateKey getPrivateKey(String alias) {
-        return km.getPrivateKey(alias);
-    }
-
-    // Inherit chooseEngineClientAlias() and chooseEngineServerAlias() from
-    // X509ExtendedKeymanager. It defines them to return null;
-}
-
-
-// Dummy X509KeyManager implementation, never returns any certificates/keys.
-// Used if the application did not specify a proper X509TrustManager.
-final class DummyX509KeyManager extends X509ExtendedKeyManager {
-
-    static final X509ExtendedKeyManager INSTANCE = new DummyX509KeyManager();
-
-    private DummyX509KeyManager() {
-        // empty
-    }
-
-    /*
-     * Get the matching aliases for authenticating the client side of a secure
-     * socket given the public key type and the list of
-     * certificate issuer authorities recognized by the peer (if any).
-     */
-    public String[] getClientAliases(String keyType, Principal[] issuers) {
-        return null;
-    }
-
-    /*
-     * Choose an alias to authenticate the client side of a secure
-     * socket given the public key type and the list of
-     * certificate issuer authorities recognized by the peer (if any).
-     */
-    public String chooseClientAlias(String[] keyTypes, Principal[] issuers,
-            Socket socket) {
-        return null;
-    }
-
-    /*
-     * Choose an alias to authenticate the client side of an
-     * engine given the public key type and the list of
-     * certificate issuer authorities recognized by the peer (if any).
-     */
-    public String chooseEngineClientAlias(
-            String[] keyTypes, Principal[] issuers, SSLEngine engine) {
-        return null;
-    }
-
-    /*
-     * Get the matching aliases for authenticating the server side of a secure
-     * socket given the public key type and the list of
-     * certificate issuer authorities recognized by the peer (if any).
-     */
-    public String[] getServerAliases(String keyType, Principal[] issuers) {
-        return null;
-    }
-
-    /*
-     * Choose an alias to authenticate the server side of a secure
-     * socket given the public key type and the list of
-     * certificate issuer authorities recognized by the peer (if any).
-     */
-    public String chooseServerAlias(String keyType, Principal[] issuers,
-            Socket socket) {
-        return null;
-    }
-
-    /*
-     * Choose an alias to authenticate the server side of an engine
-     * given the public key type and the list of
-     * certificate issuer authorities recognized by the peer (if any).
-     */
-    public String chooseEngineServerAlias(
-            String keyType, Principal[] issuers, SSLEngine engine) {
-        return null;
-    }
-
-    /**
-     * Returns the certificate chain associated with the given alias.
-     *
-     * @param alias the alias name
-     *
-     * @return the certificate chain (ordered with the user's certificate first
-     * and the root certificate authority last)
-     */
-    public X509Certificate[] getCertificateChain(String alias) {
-        return null;
-    }
-
-    /*
-     * Returns the key associated with the given alias, using the given
-     * password to recover it.
-     *
-     * @param alias the alias name
-     *
-     * @return the requested key
-     */
-    public PrivateKey getPrivateKey(String alias) {
-        return null;
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/SSLEngineImpl.java b/ojluni/src/main/java/sun/security/ssl/SSLEngineImpl.java
deleted file mode 100755
index afcbd51..0000000
--- a/ojluni/src/main/java/sun/security/ssl/SSLEngineImpl.java
+++ /dev/null
@@ -1,2087 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.nio.*;
-import java.nio.ReadOnlyBufferException;
-import java.util.LinkedList;
-import java.security.*;
-
-import javax.crypto.BadPaddingException;
-
-import javax.net.ssl.*;
-import javax.net.ssl.SSLEngineResult.*;
-
-import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager;
-
-/**
- * Implementation of an non-blocking SSLEngine.
- *
- * *Currently*, the SSLEngine code exists in parallel with the current
- * SSLSocket.  As such, the current implementation is using legacy code
- * with many of the same abstractions.  However, it varies in many
- * areas, most dramatically in the IO handling.
- *
- * There are three main I/O threads that can be existing in parallel:
- * wrap(), unwrap(), and beginHandshake().  We are encouraging users to
- * not call multiple instances of wrap or unwrap, because the data could
- * appear to flow out of the SSLEngine in a non-sequential order.  We
- * take all steps we can to at least make sure the ordering remains
- * consistent, but once the calls returns, anything can happen.  For
- * example, thread1 and thread2 both call wrap, thread1 gets the first
- * packet, thread2 gets the second packet, but thread2 gets control back
- * before thread1, and sends the data.  The receiving side would see an
- * out-of-order error.
- *
- * Handshaking is still done the same way as SSLSocket using the normal
- * InputStream/OutputStream abstactions.  We create
- * ClientHandshakers/ServerHandshakers, which produce/consume the
- * handshaking data.  The transfer of the data is largely handled by the
- * HandshakeInStream/HandshakeOutStreams.  Lastly, the
- * InputRecord/OutputRecords still have the same functionality, except
- * that they are overridden with EngineInputRecord/EngineOutputRecord,
- * which provide SSLEngine-specific functionality.
- *
- * Some of the major differences are:
- *
- * EngineInputRecord/EngineOutputRecord/EngineWriter:
- *
- *      In order to avoid writing whole new control flows for
- *      handshaking, and to reuse most of the same code, we kept most
- *      of the actual handshake code the same.  As usual, reading
- *      handshake data may trigger output of more handshake data, so
- *      what we do is write this data to internal buffers, and wait for
- *      wrap() to be called to give that data a ride.
- *
- *      All data is routed through
- *      EngineInputRecord/EngineOutputRecord.  However, all handshake
- *      data (ct_alert/ct_change_cipher_spec/ct_handshake) are passed
- *      through to the the underlying InputRecord/OutputRecord, and
- *      the data uses the internal buffers.
- *
- *      Application data is handled slightly different, we copy the data
- *      directly from the src to the dst buffers, and do all operations
- *      on those buffers, saving the overhead of multiple copies.
- *
- *      In the case of an inbound record, unwrap passes the inbound
- *      ByteBuffer to the InputRecord.  If the data is handshake data,
- *      the data is read into the InputRecord's internal buffer.  If
- *      the data is application data, the data is decoded directly into
- *      the dst buffer.
- *
- *      In the case of an outbound record, when the write to the
- *      "real" OutputStream's would normally take place, instead we
- *      call back up to the EngineOutputRecord's version of
- *      writeBuffer, at which time we capture the resulting output in a
- *      ByteBuffer, and send that back to the EngineWriter for internal
- *      storage.
- *
- *      EngineWriter is responsible for "handling" all outbound
- *      data, be it handshake or app data, and for returning the data
- *      to wrap() in the proper order.
- *
- * ClientHandshaker/ServerHandshaker/Handshaker:
- *      Methods which relied on SSLSocket now have work on either
- *      SSLSockets or SSLEngines.
- *
- * @author Brad Wetmore
- */
-final public class SSLEngineImpl extends SSLEngine {
-
-    //
-    // Fields and global comments
-    //
-
-    /*
-     * There's a state machine associated with each connection, which
-     * among other roles serves to negotiate session changes.
-     *
-     * - START with constructor, until the TCP connection's around.
-     * - HANDSHAKE picks session parameters before allowing traffic.
-     *          There are many substates due to sequencing requirements
-     *          for handshake messages.
-     * - DATA may be transmitted.
-     * - RENEGOTIATE state allows concurrent data and handshaking
-     *          traffic ("same" substates as HANDSHAKE), and terminates
-     *          in selection of new session (and connection) parameters
-     * - ERROR state immediately precedes abortive disconnect.
-     * - CLOSED when one side closes down, used to start the shutdown
-     *          process.  SSL connection objects are not reused.
-     *
-     * State affects what SSL record types may legally be sent:
-     *
-     * - Handshake ... only in HANDSHAKE and RENEGOTIATE states
-     * - App Data ... only in DATA and RENEGOTIATE states
-     * - Alert ... in HANDSHAKE, DATA, RENEGOTIATE
-     *
-     * Re what may be received:  same as what may be sent, except that
-     * HandshakeRequest handshaking messages can come from servers even
-     * in the application data state, to request entry to RENEGOTIATE.
-     *
-     * The state machine within HANDSHAKE and RENEGOTIATE states controls
-     * the pending session, not the connection state, until the change
-     * cipher spec and "Finished" handshake messages are processed and
-     * make the "new" session become the current one.
-     *
-     * NOTE: details of the SMs always need to be nailed down better.
-     * The text above illustrates the core ideas.
-     *
-     *                +---->-------+------>--------->-------+
-     *                |            |                        |
-     *     <-----<    ^            ^  <-----<               |
-     *START>----->HANDSHAKE>----->DATA>----->RENEGOTIATE    |
-     *                v            v               v        |
-     *                |            |               |        |
-     *                +------------+---------------+        |
-     *                |                                     |
-     *                v                                     |
-     *               ERROR>------>----->CLOSED<--------<----+
-     *
-     * ALSO, note that the the purpose of handshaking (renegotiation is
-     * included) is to assign a different, and perhaps new, session to
-     * the connection.  The SSLv3 spec is a bit confusing on that new
-     * protocol feature.
-     */
-    private int                 connectionState;
-
-    private static final int    cs_START = 0;
-    private static final int    cs_HANDSHAKE = 1;
-    private static final int    cs_DATA = 2;
-    private static final int    cs_RENEGOTIATE = 3;
-    private static final int    cs_ERROR = 4;
-    private static final int    cs_CLOSED = 6;
-
-    /*
-     * Once we're in state cs_CLOSED, we can continue to
-     * wrap/unwrap until we finish sending/receiving the messages
-     * for close_notify.  EngineWriter handles outboundDone.
-     */
-    private boolean             inboundDone = false;
-
-    EngineWriter                writer;
-
-    /*
-     * The authentication context holds all information used to establish
-     * who this end of the connection is (certificate chains, private keys,
-     * etc) and who is trusted (e.g. as CAs or websites).
-     */
-    private SSLContextImpl      sslContext;
-
-    /*
-     * This connection is one of (potentially) many associated with
-     * any given session.  The output of the handshake protocol is a
-     * new session ... although all the protocol description talks
-     * about changing the cipher spec (and it does change), in fact
-     * that's incidental since it's done by changing everything that
-     * is associated with a session at the same time.  (TLS/IETF may
-     * change that to add client authentication w/o new key exchg.)
-     */
-    private Handshaker                  handshaker;
-    private SSLSessionImpl              sess;
-    private volatile SSLSessionImpl     handshakeSession;
-
-
-    /*
-     * Client authentication be off, requested, or required.
-     *
-     * This will be used by both this class and SSLSocket's variants.
-     */
-    static final byte           clauth_none = 0;
-    static final byte           clauth_requested = 1;
-    static final byte           clauth_required = 2;
-
-    /*
-     * Flag indicating if the next record we receive MUST be a Finished
-     * message. Temporarily set during the handshake to ensure that
-     * a change cipher spec message is followed by a finished message.
-     */
-    private boolean             expectingFinished;
-
-
-    /*
-     * If someone tries to closeInbound() (say at End-Of-Stream)
-     * our engine having received a close_notify, we need to
-     * notify the app that we may have a truncation attack underway.
-     */
-    private boolean             recvCN;
-
-    /*
-     * For improved diagnostics, we detail connection closure
-     * If the engine is closed (connectionState >= cs_ERROR),
-     * closeReason != null indicates if the engine was closed
-     * because of an error or because or normal shutdown.
-     */
-    private SSLException        closeReason;
-
-    /*
-     * Per-connection private state that doesn't change when the
-     * session is changed.
-     */
-    private byte                        doClientAuth;
-    private boolean                     enableSessionCreation = true;
-    EngineInputRecord                   inputRecord;
-    EngineOutputRecord                  outputRecord;
-    private AccessControlContext        acc;
-
-    // The cipher suites enabled for use on this connection.
-    private CipherSuiteList             enabledCipherSuites;
-
-    // the endpoint identification protocol
-    private String                      identificationProtocol = null;
-
-    // The cryptographic algorithm constraints
-    private AlgorithmConstraints        algorithmConstraints = null;
-
-    // Have we been told whether we're client or server?
-    private boolean                     serverModeSet = false;
-    private boolean                     roleIsServer;
-
-    /*
-     * The protocol versions enabled for use on this connection.
-     *
-     * Note: we support a pseudo protocol called SSLv2Hello which when
-     * set will result in an SSL v2 Hello being sent with SSL (version 3.0)
-     * or TLS (version 3.1, 3.2, etc.) version info.
-     */
-    private ProtocolList        enabledProtocols;
-
-    /*
-     * The SSL version associated with this connection.
-     */
-    private ProtocolVersion     protocolVersion = ProtocolVersion.DEFAULT;
-
-    /*
-     * Crypto state that's reinitialized when the session changes.
-     */
-    private MAC                 readMAC, writeMAC;
-    private CipherBox           readCipher, writeCipher;
-    // NOTE: compression state would be saved here
-
-    /*
-     * security parameters for secure renegotiation.
-     */
-    private boolean             secureRenegotiation;
-    private byte[]              clientVerifyData;
-    private byte[]              serverVerifyData;
-
-    /*
-     * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
-     * IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES.
-     * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
-     *
-     * There are several locks here.
-     *
-     * The primary lock is the per-instance lock used by
-     * synchronized(this) and the synchronized methods.  It controls all
-     * access to things such as the connection state and variables which
-     * affect handshaking.  If we are inside a synchronized method, we
-     * can access the state directly, otherwise, we must use the
-     * synchronized equivalents.
-     *
-     * Note that we must never acquire the <code>this</code> lock after
-     * <code>writeLock</code> or run the risk of deadlock.
-     *
-     * Grab some coffee, and be careful with any code changes.
-     */
-    private Object              wrapLock;
-    private Object              unwrapLock;
-    Object                      writeLock;
-
-    /*
-     * Is it the first application record to write?
-     */
-    private boolean isFirstAppOutputRecord = true;
-
-    /*
-     * Class and subclass dynamic debugging support
-     */
-    private static final Debug debug = Debug.getInstance("ssl");
-
-    //
-    // Initialization/Constructors
-    //
-
-    /**
-     * Constructor for an SSLEngine from SSLContext, without
-     * host/port hints.  This Engine will not be able to cache
-     * sessions, but must renegotiate everything by hand.
-     */
-    SSLEngineImpl(SSLContextImpl ctx) {
-        super();
-        init(ctx);
-    }
-
-    /**
-     * Constructor for an SSLEngine from SSLContext.
-     */
-    SSLEngineImpl(SSLContextImpl ctx, String host, int port) {
-        super(host, port);
-        init(ctx);
-    }
-
-    /**
-     * Initializes the Engine
-     */
-    private void init(SSLContextImpl ctx) {
-        if (debug != null && Debug.isOn("ssl")) {
-            System.out.println("Using SSLEngineImpl.");
-        }
-
-        sslContext = ctx;
-        sess = SSLSessionImpl.nullSession;
-        handshakeSession = null;
-
-        /*
-         * State is cs_START until we initialize the handshaker.
-         *
-         * Apps using SSLEngine are probably going to be server.
-         * Somewhat arbitrary choice.
-         */
-        roleIsServer = true;
-        connectionState = cs_START;
-
-        /*
-         * default read and write side cipher and MAC support
-         *
-         * Note:  compression support would go here too
-         */
-        readCipher = CipherBox.NULL;
-        readMAC = MAC.NULL;
-        writeCipher = CipherBox.NULL;
-        writeMAC = MAC.NULL;
-
-        // default security parameters for secure renegotiation
-        secureRenegotiation = false;
-        clientVerifyData = new byte[0];
-        serverVerifyData = new byte[0];
-
-        enabledCipherSuites =
-                sslContext.getDefaultCipherSuiteList(roleIsServer);
-        enabledProtocols =
-                sslContext.getDefaultProtocolList(roleIsServer);
-
-        wrapLock = new Object();
-        unwrapLock = new Object();
-        writeLock = new Object();
-
-        /*
-         * Save the Access Control Context.  This will be used later
-         * for a couple of things, including providing a context to
-         * run tasks in, and for determining which credentials
-         * to use for Subject based (JAAS) decisions
-         */
-        acc = AccessController.getContext();
-
-        /*
-         * All outbound application data goes through this OutputRecord,
-         * other data goes through their respective records created
-         * elsewhere.  All inbound data goes through this one
-         * input record.
-         */
-        outputRecord =
-            new EngineOutputRecord(Record.ct_application_data, this);
-        inputRecord = new EngineInputRecord(this);
-        inputRecord.enableFormatChecks();
-
-        writer = new EngineWriter();
-    }
-
-    /**
-     * Initialize the handshaker object. This means:
-     *
-     *  . if a handshake is already in progress (state is cs_HANDSHAKE
-     *    or cs_RENEGOTIATE), do nothing and return
-     *
-     *  . if the engine is already closed, throw an Exception (internal error)
-     *
-     *  . otherwise (cs_START or cs_DATA), create the appropriate handshaker
-     *    object and advance the connection state (to cs_HANDSHAKE or
-     *    cs_RENEGOTIATE, respectively).
-     *
-     * This method is called right after a new engine is created, when
-     * starting renegotiation, or when changing client/server mode of the
-     * engine.
-     */
-    private void initHandshaker() {
-        switch (connectionState) {
-
-        //
-        // Starting a new handshake.
-        //
-        case cs_START:
-        case cs_DATA:
-            break;
-
-        //
-        // We're already in the middle of a handshake.
-        //
-        case cs_HANDSHAKE:
-        case cs_RENEGOTIATE:
-            return;
-
-        //
-        // Anyone allowed to call this routine is required to
-        // do so ONLY if the connection state is reasonable...
-        //
-        default:
-            throw new IllegalStateException("Internal error");
-        }
-
-        // state is either cs_START or cs_DATA
-        if (connectionState == cs_START) {
-            connectionState = cs_HANDSHAKE;
-        } else { // cs_DATA
-            connectionState = cs_RENEGOTIATE;
-        }
-        if (roleIsServer) {
-            handshaker = new ServerHandshaker(this, sslContext,
-                    enabledProtocols, doClientAuth,
-                    protocolVersion, connectionState == cs_HANDSHAKE,
-                    secureRenegotiation, clientVerifyData, serverVerifyData);
-        } else {
-            handshaker = new ClientHandshaker(this, sslContext,
-                    enabledProtocols,
-                    protocolVersion, connectionState == cs_HANDSHAKE,
-                    secureRenegotiation, clientVerifyData, serverVerifyData);
-        }
-        handshaker.setEnabledCipherSuites(enabledCipherSuites);
-        handshaker.setEnableSessionCreation(enableSessionCreation);
-    }
-
-    /*
-     * Report the current status of the Handshaker
-     */
-    private HandshakeStatus getHSStatus(HandshakeStatus hss) {
-
-        if (hss != null) {
-            return hss;
-        }
-
-        synchronized (this) {
-            if (writer.hasOutboundData()) {
-                return HandshakeStatus.NEED_WRAP;
-            } else if (handshaker != null) {
-                if (handshaker.taskOutstanding()) {
-                    return HandshakeStatus.NEED_TASK;
-                } else {
-                    return HandshakeStatus.NEED_UNWRAP;
-                }
-            } else if (connectionState == cs_CLOSED) {
-                /*
-                 * Special case where we're closing, but
-                 * still need the close_notify before we
-                 * can officially be closed.
-                 *
-                 * Note isOutboundDone is taken care of by
-                 * hasOutboundData() above.
-                 */
-                if (!isInboundDone()) {
-                    return HandshakeStatus.NEED_UNWRAP;
-                } // else not handshaking
-            }
-
-            return HandshakeStatus.NOT_HANDSHAKING;
-        }
-    }
-
-    synchronized private void checkTaskThrown() throws SSLException {
-        if (handshaker != null) {
-            handshaker.checkThrown();
-        }
-    }
-
-    //
-    // Handshaking and connection state code
-    //
-
-    /*
-     * Provides "this" synchronization for connection state.
-     * Otherwise, you can access it directly.
-     */
-    synchronized private int getConnectionState() {
-        return connectionState;
-    }
-
-    synchronized private void setConnectionState(int state) {
-        connectionState = state;
-    }
-
-    /*
-     * Get the Access Control Context.
-     *
-     * Used for a known context to
-     * run tasks in, and for determining which credentials
-     * to use for Subject-based (JAAS) decisions.
-     */
-    AccessControlContext getAcc() {
-        return acc;
-    }
-
-    /*
-     * Is a handshake currently underway?
-     */
-    public SSLEngineResult.HandshakeStatus getHandshakeStatus() {
-        return getHSStatus(null);
-    }
-
-    /*
-     * When a connection finishes handshaking by enabling use of a newly
-     * negotiated session, each end learns about it in two halves (read,
-     * and write).  When both read and write ciphers have changed, and the
-     * last handshake message has been read, the connection has joined
-     * (rejoined) the new session.
-     *
-     * NOTE:  The SSLv3 spec is rather unclear on the concepts here.
-     * Sessions don't change once they're established (including cipher
-     * suite and master secret) but connections can join them (and leave
-     * them).  They're created by handshaking, though sometime handshaking
-     * causes connections to join up with pre-established sessions.
-     *
-     * Synchronized on "this" from readRecord.
-     */
-    private void changeReadCiphers() throws SSLException {
-        if (connectionState != cs_HANDSHAKE
-                && connectionState != cs_RENEGOTIATE) {
-            throw new SSLProtocolException(
-                "State error, change cipher specs");
-        }
-
-        // ... create decompressor
-
-        CipherBox oldCipher = readCipher;
-
-        try {
-            readCipher = handshaker.newReadCipher();
-            readMAC = handshaker.newReadMAC();
-        } catch (GeneralSecurityException e) {
-            // "can't happen"
-            throw (SSLException)new SSLException
-                                ("Algorithm missing:  ").initCause(e);
-        }
-
-        /*
-         * Dispose of any intermediate state in the underlying cipher.
-         * For PKCS11 ciphers, this will release any attached sessions,
-         * and thus make finalization faster.
-         *
-         * Since MAC's doFinal() is called for every SSL/TLS packet, it's
-         * not necessary to do the same with MAC's.
-         */
-        oldCipher.dispose();
-    }
-
-    /*
-     * used by Handshaker to change the active write cipher, follows
-     * the output of the CCS message.
-     *
-     * Also synchronized on "this" from readRecord/delegatedTask.
-     */
-    void changeWriteCiphers() throws SSLException {
-        if (connectionState != cs_HANDSHAKE
-                && connectionState != cs_RENEGOTIATE) {
-            throw new SSLProtocolException(
-                "State error, change cipher specs");
-        }
-
-        // ... create compressor
-
-        CipherBox oldCipher = writeCipher;
-
-        try {
-            writeCipher = handshaker.newWriteCipher();
-            writeMAC = handshaker.newWriteMAC();
-        } catch (GeneralSecurityException e) {
-            // "can't happen"
-            throw (SSLException)new SSLException
-                                ("Algorithm missing:  ").initCause(e);
-        }
-
-        // See comment above.
-        oldCipher.dispose();
-
-        // reset the flag of the first application record
-        isFirstAppOutputRecord = true;
-    }
-
-    /*
-     * Updates the SSL version associated with this connection.
-     * Called from Handshaker once it has determined the negotiated version.
-     */
-    synchronized void setVersion(ProtocolVersion protocolVersion) {
-        this.protocolVersion = protocolVersion;
-        outputRecord.setVersion(protocolVersion);
-    }
-
-
-    /**
-     * Kickstart the handshake if it is not already in progress.
-     * This means:
-     *
-     *  . if handshaking is already underway, do nothing and return
-     *
-     *  . if the engine is not connected or already closed, throw an
-     *    Exception.
-     *
-     *  . otherwise, call initHandshake() to initialize the handshaker
-     *    object and progress the state. Then, send the initial
-     *    handshaking message if appropriate (always on clients and
-     *    on servers when renegotiating).
-     */
-    private synchronized void kickstartHandshake() throws IOException {
-        switch (connectionState) {
-
-        case cs_START:
-            if (!serverModeSet) {
-                throw new IllegalStateException(
-                    "Client/Server mode not yet set.");
-            }
-            initHandshaker();
-            break;
-
-        case cs_HANDSHAKE:
-            // handshaker already setup, proceed
-            break;
-
-        case cs_DATA:
-            if (!secureRenegotiation && !Handshaker.allowUnsafeRenegotiation) {
-                throw new SSLHandshakeException(
-                        "Insecure renegotiation is not allowed");
-            }
-
-            if (!secureRenegotiation) {
-                if (debug != null && Debug.isOn("handshake")) {
-                    System.out.println(
-                        "Warning: Using insecure renegotiation");
-                }
-            }
-
-            // initialize the handshaker, move to cs_RENEGOTIATE
-            initHandshaker();
-            break;
-
-        case cs_RENEGOTIATE:
-            // handshaking already in progress, return
-            return;
-
-        default:
-            // cs_ERROR/cs_CLOSED
-            throw new SSLException("SSLEngine is closing/closed");
-        }
-
-        //
-        // Kickstart handshake state machine if we need to ...
-        //
-        // Note that handshaker.kickstart() writes the message
-        // to its HandshakeOutStream, which calls back into
-        // SSLSocketImpl.writeRecord() to send it.
-        //
-        if (!handshaker.activated()) {
-             // prior to handshaking, activate the handshake
-            if (connectionState == cs_RENEGOTIATE) {
-                // don't use SSLv2Hello when renegotiating
-                handshaker.activate(protocolVersion);
-            } else {
-                handshaker.activate(null);
-            }
-
-            if (handshaker instanceof ClientHandshaker) {
-                // send client hello
-                handshaker.kickstart();
-            } else {    // instanceof ServerHandshaker
-                if (connectionState == cs_HANDSHAKE) {
-                    // initial handshake, no kickstart message to send
-                } else {
-                    // we want to renegotiate, send hello request
-                    handshaker.kickstart();
-
-                    // hello request is not included in the handshake
-                    // hashes, reset them
-                    handshaker.handshakeHash.reset();
-                }
-            }
-        }
-    }
-
-    /*
-     * Start a SSLEngine handshake
-     */
-    public void beginHandshake() throws SSLException {
-        try {
-            kickstartHandshake();
-        } catch (Exception e) {
-            fatal(Alerts.alert_handshake_failure,
-                "Couldn't kickstart handshaking", e);
-        }
-    }
-
-
-    //
-    // Read/unwrap side
-    //
-
-
-    /**
-     * Unwraps a buffer.  Does a variety of checks before grabbing
-     * the unwrapLock, which blocks multiple unwraps from occuring.
-     */
-    public SSLEngineResult unwrap(ByteBuffer netData, ByteBuffer [] appData,
-            int offset, int length) throws SSLException {
-
-        EngineArgs ea = new EngineArgs(netData, appData, offset, length);
-
-        try {
-            synchronized (unwrapLock) {
-                return readNetRecord(ea);
-            }
-        } catch (Exception e) {
-            /*
-             * Don't reset position so it looks like we didn't
-             * consume anything.  We did consume something, and it
-             * got us into this situation, so report that much back.
-             * Our days of consuming are now over anyway.
-             */
-            fatal(Alerts.alert_internal_error,
-                "problem unwrapping net record", e);
-            return null;  // make compiler happy
-        } finally {
-            /*
-             * Just in case something failed to reset limits properly.
-             */
-            ea.resetLim();
-        }
-    }
-
-    /*
-     * Makes additional checks for unwrap, but this time more
-     * specific to this packet and the current state of the machine.
-     */
-    private SSLEngineResult readNetRecord(EngineArgs ea) throws IOException {
-
-        Status status = null;
-        HandshakeStatus hsStatus = null;
-
-        /*
-         * See if the handshaker needs to report back some SSLException.
-         */
-        checkTaskThrown();
-
-        /*
-         * Check if we are closing/closed.
-         */
-        if (isInboundDone()) {
-            return new SSLEngineResult(Status.CLOSED, getHSStatus(null), 0, 0);
-        }
-
-        /*
-         * If we're still in cs_HANDSHAKE, make sure it's been
-         * started.
-         */
-        synchronized (this) {
-            if ((connectionState == cs_HANDSHAKE) ||
-                    (connectionState == cs_START)) {
-                kickstartHandshake();
-
-                /*
-                 * If there's still outbound data to flush, we
-                 * can return without trying to unwrap anything.
-                 */
-                hsStatus = getHSStatus(null);
-
-                if (hsStatus == HandshakeStatus.NEED_WRAP) {
-                    return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
-                }
-            }
-        }
-
-        /*
-         * Grab a copy of this if it doesn't already exist,
-         * and we can use it several places before anything major
-         * happens on this side.  Races aren't critical
-         * here.
-         */
-        if (hsStatus == null) {
-            hsStatus = getHSStatus(null);
-        }
-
-        /*
-         * If we have a task outstanding, this *MUST* be done before
-         * doing any more unwrapping, because we could be in the middle
-         * of receiving a handshake message, for example, a finished
-         * message which would change the ciphers.
-         */
-        if (hsStatus == HandshakeStatus.NEED_TASK) {
-            return new SSLEngineResult(
-                Status.OK, hsStatus, 0, 0);
-        }
-
-        /*
-         * Check the packet to make sure enough is here.
-         * This will also indirectly check for 0 len packets.
-         */
-        int packetLen = inputRecord.bytesInCompletePacket(ea.netData);
-
-        // Is this packet bigger than SSL/TLS normally allows?
-        if (packetLen > sess.getPacketBufferSize()) {
-            if (packetLen > Record.maxLargeRecordSize) {
-                throw new SSLProtocolException(
-                    "Input SSL/TLS record too big: max = " +
-                    Record.maxLargeRecordSize +
-                    " len = " + packetLen);
-            } else {
-                // Expand the expected maximum packet/application buffer
-                // sizes.
-                sess.expandBufferSizes();
-            }
-        }
-
-        /*
-         * Check for OVERFLOW.
-         *
-         * To be considered: We could delay enforcing the application buffer
-         * free space requirement until after the initial handshaking.
-         */
-        if ((packetLen - Record.headerSize) > ea.getAppRemaining()) {
-            return new SSLEngineResult(Status.BUFFER_OVERFLOW, hsStatus, 0, 0);
-        }
-
-        // check for UNDERFLOW.
-        if ((packetLen == -1) || (ea.netData.remaining() < packetLen)) {
-            return new SSLEngineResult(
-                Status.BUFFER_UNDERFLOW, hsStatus, 0, 0);
-        }
-
-        /*
-         * We're now ready to actually do the read.
-         * The only result code we really need to be exactly
-         * right is the HS finished, for signaling to
-         * HandshakeCompletedListeners.
-         */
-        try {
-            hsStatus = readRecord(ea);
-        } catch (SSLException e) {
-            throw e;
-        } catch (IOException e) {
-            SSLException ex = new SSLException("readRecord");
-            ex.initCause(e);
-            throw ex;
-        }
-
-        /*
-         * Check the various condition that we could be reporting.
-         *
-         * It's *possible* something might have happened between the
-         * above and now, but it was better to minimally lock "this"
-         * during the read process.  We'll return the current
-         * status, which is more representative of the current state.
-         *
-         * status above should cover:  FINISHED, NEED_TASK
-         */
-        status = (isInboundDone() ? Status.CLOSED : Status.OK);
-        hsStatus = getHSStatus(hsStatus);
-
-        return new SSLEngineResult(status, hsStatus,
-            ea.deltaNet(), ea.deltaApp());
-    }
-
-    /*
-     * Actually do the read record processing.
-     *
-     * Returns a Status if it can make specific determinations
-     * of the engine state.  In particular, we need to signal
-     * that a handshake just completed.
-     *
-     * It would be nice to be symmetrical with the write side and move
-     * the majority of this to EngineInputRecord, but there's too much
-     * SSLEngine state to do that cleanly.  It must still live here.
-     */
-    private HandshakeStatus readRecord(EngineArgs ea) throws IOException {
-
-        HandshakeStatus hsStatus = null;
-
-        /*
-         * The various operations will return new sliced BB's,
-         * this will avoid having to worry about positions and
-         * limits in the netBB.
-         */
-        ByteBuffer readBB = null;
-        ByteBuffer decryptedBB = null;
-
-        if (getConnectionState() != cs_ERROR) {
-
-            /*
-             * Read a record ... maybe emitting an alert if we get a
-             * comprehensible but unsupported "hello" message during
-             * format checking (e.g. V2).
-             */
-            try {
-                readBB = inputRecord.read(ea.netData);
-            } catch (IOException e) {
-                fatal(Alerts.alert_unexpected_message, e);
-            }
-
-            /*
-             * The basic SSLv3 record protection involves (optional)
-             * encryption for privacy, and an integrity check ensuring
-             * data origin authentication.  We do them both here, and
-             * throw a fatal alert if the integrity check fails.
-             */
-            try {
-                decryptedBB = inputRecord.decrypt(readMAC, readCipher, readBB);
-            } catch (BadPaddingException e) {
-                byte alertType = (inputRecord.contentType() ==
-                    Record.ct_handshake) ?
-                        Alerts.alert_handshake_failure :
-                        Alerts.alert_bad_record_mac;
-                fatal(alertType, e.getMessage(), e);
-            }
-
-
-            // if (!inputRecord.decompress(c))
-            //     fatal(Alerts.alert_decompression_failure,
-            //     "decompression failure");
-
-
-            /*
-             * Process the record.
-             */
-
-            synchronized (this) {
-                switch (inputRecord.contentType()) {
-                case Record.ct_handshake:
-                    /*
-                     * Handshake messages always go to a pending session
-                     * handshaker ... if there isn't one, create one.  This
-                     * must work asynchronously, for renegotiation.
-                     *
-                     * NOTE that handshaking will either resume a session
-                     * which was in the cache (and which might have other
-                     * connections in it already), or else will start a new
-                     * session (new keys exchanged) with just this connection
-                     * in it.
-                     */
-                    initHandshaker();
-                    if (!handshaker.activated()) {
-                        // prior to handshaking, activate the handshake
-                        if (connectionState == cs_RENEGOTIATE) {
-                            // don't use SSLv2Hello when renegotiating
-                            handshaker.activate(protocolVersion);
-                        } else {
-                            handshaker.activate(null);
-                        }
-                    }
-
-                    /*
-                     * process the handshake record ... may contain just
-                     * a partial handshake message or multiple messages.
-                     *
-                     * The handshaker state machine will ensure that it's
-                     * a finished message.
-                     */
-                    handshaker.process_record(inputRecord, expectingFinished);
-                    expectingFinished = false;
-
-                    if (handshaker.invalidated) {
-                        handshaker = null;
-                        // if state is cs_RENEGOTIATE, revert it to cs_DATA
-                        if (connectionState == cs_RENEGOTIATE) {
-                            connectionState = cs_DATA;
-                        }
-                    } else if (handshaker.isDone()) {
-                        // reset the parameters for secure renegotiation.
-                        secureRenegotiation =
-                                        handshaker.isSecureRenegotiation();
-                        clientVerifyData = handshaker.getClientVerifyData();
-                        serverVerifyData = handshaker.getServerVerifyData();
-
-                        sess = handshaker.getSession();
-                        handshakeSession = null;
-                        if (!writer.hasOutboundData()) {
-                            hsStatus = HandshakeStatus.FINISHED;
-                        }
-                        handshaker = null;
-                        connectionState = cs_DATA;
-
-                        // No handshakeListeners here.  That's a
-                        // SSLSocket thing.
-                    } else if (handshaker.taskOutstanding()) {
-                        hsStatus = HandshakeStatus.NEED_TASK;
-                    }
-                    break;
-
-                case Record.ct_application_data:
-                    // Pass this right back up to the application.
-                    if ((connectionState != cs_DATA)
-                            && (connectionState != cs_RENEGOTIATE)
-                            && (connectionState != cs_CLOSED)) {
-                        throw new SSLProtocolException(
-                            "Data received in non-data state: " +
-                            connectionState);
-                    }
-
-                    if (expectingFinished) {
-                        throw new SSLProtocolException
-                                ("Expecting finished message, received data");
-                    }
-
-                    /*
-                     * Don't return data once the inbound side is
-                     * closed.
-                     */
-                    if (!inboundDone) {
-                        ea.scatter(decryptedBB.slice());
-                    }
-                    break;
-
-                case Record.ct_alert:
-                    recvAlert();
-                    break;
-
-                case Record.ct_change_cipher_spec:
-                    if ((connectionState != cs_HANDSHAKE
-                                && connectionState != cs_RENEGOTIATE)
-                            || inputRecord.available() != 1
-                            || inputRecord.read() != 1) {
-                        fatal(Alerts.alert_unexpected_message,
-                            "illegal change cipher spec msg, state = "
-                            + connectionState);
-                    }
-
-                    //
-                    // The first message after a change_cipher_spec
-                    // record MUST be a "Finished" handshake record,
-                    // else it's a protocol violation.  We force this
-                    // to be checked by a minor tweak to the state
-                    // machine.
-                    //
-                    changeReadCiphers();
-                    // next message MUST be a finished message
-                    expectingFinished = true;
-                    break;
-
-                default:
-                    //
-                    // TLS requires that unrecognized records be ignored.
-                    //
-                    if (debug != null && Debug.isOn("ssl")) {
-                        System.out.println(threadName() +
-                            ", Received record type: "
-                            + inputRecord.contentType());
-                    }
-                    break;
-                } // switch
-
-                /*
-                 * We only need to check the sequence number state for
-                 * non-handshaking record.
-                 *
-                 * Note that in order to maintain the handshake status
-                 * properly, we check the sequence number after the last
-                 * record reading process. As we request renegotiation
-                 * or close the connection for wrapped sequence number
-                 * when there is enough sequence number space left to
-                 * handle a few more records, so the sequence number
-                 * of the last record cannot be wrapped.
-                 */
-                if (connectionState < cs_ERROR && !isInboundDone() &&
-                        (hsStatus == HandshakeStatus.NOT_HANDSHAKING)) {
-                    if (checkSequenceNumber(readMAC,
-                            inputRecord.contentType())) {
-                        hsStatus = getHSStatus(null);
-                    }
-                }
-            } // synchronized (this)
-        }
-
-        return hsStatus;
-    }
-
-
-    //
-    // write/wrap side
-    //
-
-
-    /**
-     * Wraps a buffer.  Does a variety of checks before grabbing
-     * the wrapLock, which blocks multiple wraps from occuring.
-     */
-    public SSLEngineResult wrap(ByteBuffer [] appData,
-            int offset, int length, ByteBuffer netData) throws SSLException {
-
-        EngineArgs ea = new EngineArgs(appData, offset, length, netData);
-
-        /*
-         * We can be smarter about using smaller buffer sizes later.
-         * For now, force it to be large enough to handle any
-         * valid SSL/TLS record.
-         */
-        if (netData.remaining() < outputRecord.maxRecordSize) {
-            return new SSLEngineResult(
-                Status.BUFFER_OVERFLOW, getHSStatus(null), 0, 0);
-        }
-
-        try {
-            synchronized (wrapLock) {
-                return writeAppRecord(ea);
-            }
-        } catch (Exception e) {
-            ea.resetPos();
-
-            fatal(Alerts.alert_internal_error,
-                "problem wrapping app data", e);
-            return null;  // make compiler happy
-        } finally {
-            /*
-             * Just in case something didn't reset limits properly.
-             */
-            ea.resetLim();
-        }
-    }
-
-    /*
-     * Makes additional checks for unwrap, but this time more
-     * specific to this packet and the current state of the machine.
-     */
-    private SSLEngineResult writeAppRecord(EngineArgs ea) throws IOException {
-
-        Status status = null;
-        HandshakeStatus hsStatus = null;
-
-        /*
-         * See if the handshaker needs to report back some SSLException.
-         */
-        checkTaskThrown();
-
-        /*
-         * short circuit if we're closed/closing.
-         */
-        if (writer.isOutboundDone()) {
-            return new SSLEngineResult(Status.CLOSED, getHSStatus(null), 0, 0);
-        }
-
-        /*
-         * If we're still in cs_HANDSHAKE, make sure it's been
-         * started.
-         */
-        synchronized (this) {
-            if ((connectionState == cs_HANDSHAKE) ||
-                    (connectionState == cs_START)) {
-                kickstartHandshake();
-
-                /*
-                 * If there's no HS data available to write, we can return
-                 * without trying to wrap anything.
-                 */
-                hsStatus = getHSStatus(null);
-
-                if (hsStatus == HandshakeStatus.NEED_UNWRAP) {
-                    return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
-                }
-            }
-        }
-
-        /*
-         * Grab a copy of this if it doesn't already exist,
-         * and we can use it several places before anything major
-         * happens on this side.  Races aren't critical
-         * here.
-         */
-        if (hsStatus == null) {
-            hsStatus = getHSStatus(null);
-        }
-
-        /*
-         * If we have a task outstanding, this *MUST* be done before
-         * doing any more wrapping, because we could be in the middle
-         * of receiving a handshake message, for example, a finished
-         * message which would change the ciphers.
-         */
-        if (hsStatus == HandshakeStatus.NEED_TASK) {
-            return new SSLEngineResult(
-                Status.OK, hsStatus, 0, 0);
-        }
-
-        /*
-         * This will obtain any waiting outbound data, or will
-         * process the outbound appData.
-         */
-        try {
-            synchronized (writeLock) {
-                hsStatus = writeRecord(outputRecord, ea);
-            }
-        } catch (SSLException e) {
-            throw e;
-        } catch (IOException e) {
-            SSLException ex = new SSLException("Write problems");
-            ex.initCause(e);
-            throw ex;
-        }
-
-        /*
-         * writeRecord might have reported some status.
-         * Now check for the remaining cases.
-         *
-         * status above should cover:  NEED_WRAP/FINISHED
-         */
-        status = (isOutboundDone() ? Status.CLOSED : Status.OK);
-        hsStatus = getHSStatus(hsStatus);
-
-        return new SSLEngineResult(status, hsStatus,
-            ea.deltaApp(), ea.deltaNet());
-    }
-
-    /*
-     * Central point to write/get all of the outgoing data.
-     */
-    private HandshakeStatus writeRecord(EngineOutputRecord eor,
-            EngineArgs ea) throws IOException {
-
-        // eventually compress as well.
-        HandshakeStatus hsStatus =
-                writer.writeRecord(eor, ea, writeMAC, writeCipher);
-
-        /*
-         * We only need to check the sequence number state for
-         * non-handshaking record.
-         *
-         * Note that in order to maintain the handshake status
-         * properly, we check the sequence number after the last
-         * record writing process. As we request renegotiation
-         * or close the connection for wrapped sequence number
-         * when there is enough sequence number space left to
-         * handle a few more records, so the sequence number
-         * of the last record cannot be wrapped.
-         */
-        if (connectionState < cs_ERROR && !isOutboundDone() &&
-                (hsStatus == HandshakeStatus.NOT_HANDSHAKING)) {
-            if (checkSequenceNumber(writeMAC, eor.contentType())) {
-                hsStatus = getHSStatus(null);
-            }
-        }
-
-        /*
-         * turn off the flag of the first application record if we really
-         * consumed at least byte.
-         */
-        if (isFirstAppOutputRecord && ea.deltaApp() > 0) {
-            isFirstAppOutputRecord = false;
-        }
-
-        return hsStatus;
-    }
-
-    /*
-     * Need to split the payload except the following cases:
-     *
-     * 1. protocol version is TLS 1.1 or later;
-     * 2. bulk cipher does not use CBC mode, including null bulk cipher suites.
-     * 3. the payload is the first application record of a freshly
-     *    negotiated TLS session.
-     * 4. the CBC protection is disabled;
-     *
-     * More details, please refer to
-     * EngineOutputRecord.write(EngineArgs, MAC, CipherBox).
-     */
-    boolean needToSplitPayload(CipherBox cipher, ProtocolVersion protocol) {
-        return (protocol.v <= ProtocolVersion.TLS10.v) &&
-                cipher.isCBCMode() && !isFirstAppOutputRecord &&
-                Record.enableCBCProtection;
-    }
-
-    /*
-     * Non-application OutputRecords go through here.
-     */
-    void writeRecord(EngineOutputRecord eor) throws IOException {
-        // eventually compress as well.
-        writer.writeRecord(eor, writeMAC, writeCipher);
-
-        /*
-         * Check the sequence number state
-         *
-         * Note that in order to maintain the connection I/O
-         * properly, we check the sequence number after the last
-         * record writing process. As we request renegotiation
-         * or close the connection for wrapped sequence number
-         * when there is enough sequence number space left to
-         * handle a few more records, so the sequence number
-         * of the last record cannot be wrapped.
-         */
-        if ((connectionState < cs_ERROR) && !isOutboundDone()) {
-            checkSequenceNumber(writeMAC, eor.contentType());
-        }
-    }
-
-    //
-    // Close code
-    //
-
-    /**
-     * Check the sequence number state
-     *
-     * RFC 4346 states that, "Sequence numbers are of type uint64 and
-     * may not exceed 2^64-1.  Sequence numbers do not wrap. If a TLS
-     * implementation would need to wrap a sequence number, it must
-     * renegotiate instead."
-     *
-     * Return true if the handshake status may be changed.
-     */
-    private boolean checkSequenceNumber(MAC mac, byte type)
-            throws IOException {
-
-        /*
-         * Don't bother to check the sequence number for error or
-         * closed connections, or NULL MAC
-         */
-        if (connectionState >= cs_ERROR || mac == MAC.NULL) {
-            return false;
-        }
-
-        /*
-         * Conservatively, close the connection immediately when the
-         * sequence number is close to overflow
-         */
-        if (mac.seqNumOverflow()) {
-            /*
-             * TLS protocols do not define a error alert for sequence
-             * number overflow. We use handshake_failure error alert
-             * for handshaking and bad_record_mac for other records.
-             */
-            if (debug != null && Debug.isOn("ssl")) {
-                System.out.println(threadName() +
-                    ", sequence number extremely close to overflow " +
-                    "(2^64-1 packets). Closing connection.");
-            }
-
-            fatal(Alerts.alert_handshake_failure, "sequence number overflow");
-
-            return true; // make the compiler happy
-        }
-
-        /*
-         * Ask for renegotiation when need to renew sequence number.
-         *
-         * Don't bother to kickstart the renegotiation when the local is
-         * asking for it.
-         */
-        if ((type != Record.ct_handshake) && mac.seqNumIsHuge()) {
-            if (debug != null && Debug.isOn("ssl")) {
-                System.out.println(threadName() + ", request renegotiation " +
-                        "to avoid sequence number overflow");
-            }
-
-            beginHandshake();
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Signals that no more outbound application data will be sent
-     * on this <code>SSLEngine</code>.
-     */
-    private void closeOutboundInternal() {
-
-        if ((debug != null) && Debug.isOn("ssl")) {
-            System.out.println(threadName() + ", closeOutboundInternal()");
-        }
-
-        /*
-         * Already closed, ignore
-         */
-        if (writer.isOutboundDone()) {
-            return;
-        }
-
-        switch (connectionState) {
-
-        /*
-         * If we haven't even started yet, don't bother reading inbound.
-         */
-        case cs_START:
-            writer.closeOutbound();
-            inboundDone = true;
-            break;
-
-        case cs_ERROR:
-        case cs_CLOSED:
-            break;
-
-        /*
-         * Otherwise we indicate clean termination.
-         */
-        // case cs_HANDSHAKE:
-        // case cs_DATA:
-        // case cs_RENEGOTIATE:
-        default:
-            warning(Alerts.alert_close_notify);
-            writer.closeOutbound();
-            break;
-        }
-
-        // See comment in changeReadCiphers()
-        writeCipher.dispose();
-
-        connectionState = cs_CLOSED;
-    }
-
-    synchronized public void closeOutbound() {
-        /*
-         * Dump out a close_notify to the remote side
-         */
-        if ((debug != null) && Debug.isOn("ssl")) {
-            System.out.println(threadName() + ", called closeOutbound()");
-        }
-
-        closeOutboundInternal();
-    }
-
-    /**
-     * Returns the outbound application data closure state
-     */
-    public boolean isOutboundDone() {
-        return writer.isOutboundDone();
-    }
-
-    /**
-     * Signals that no more inbound network data will be sent
-     * to this <code>SSLEngine</code>.
-     */
-    private void closeInboundInternal() {
-
-        if ((debug != null) && Debug.isOn("ssl")) {
-            System.out.println(threadName() + ", closeInboundInternal()");
-        }
-
-        /*
-         * Already closed, ignore
-         */
-        if (inboundDone) {
-            return;
-        }
-
-        closeOutboundInternal();
-        inboundDone = true;
-
-        // See comment in changeReadCiphers()
-        readCipher.dispose();
-
-        connectionState = cs_CLOSED;
-    }
-
-    /*
-     * Close the inbound side of the connection.  We grab the
-     * lock here, and do the real work in the internal verison.
-     * We do check for truncation attacks.
-     */
-    synchronized public void closeInbound() throws SSLException {
-        /*
-         * Currently closes the outbound side as well.  The IETF TLS
-         * working group has expressed the opinion that 1/2 open
-         * connections are not allowed by the spec.  May change
-         * someday in the future.
-         */
-        if ((debug != null) && Debug.isOn("ssl")) {
-            System.out.println(threadName() + ", called closeInbound()");
-        }
-
-        /*
-         * No need to throw an Exception if we haven't even started yet.
-         */
-        if ((connectionState != cs_START) && !recvCN) {
-            recvCN = true;  // Only receive the Exception once
-            fatal(Alerts.alert_internal_error,
-                "Inbound closed before receiving peer's close_notify: " +
-                "possible truncation attack?");
-        } else {
-            /*
-             * Currently, this is a no-op, but in case we change
-             * the close inbound code later.
-             */
-            closeInboundInternal();
-        }
-    }
-
-    /**
-     * Returns the network inbound data closure state
-     */
-    synchronized public boolean isInboundDone() {
-        return inboundDone;
-    }
-
-
-    //
-    // Misc stuff
-    //
-
-
-    /**
-     * Returns the current <code>SSLSession</code> for this
-     * <code>SSLEngine</code>
-     * <P>
-     * These can be long lived, and frequently correspond to an
-     * entire login session for some user.
-     */
-    synchronized public SSLSession getSession() {
-        return sess;
-    }
-
-    @Override
-    synchronized public SSLSession getHandshakeSession() {
-        return handshakeSession;
-    }
-
-    synchronized void setHandshakeSession(SSLSessionImpl session) {
-        handshakeSession = session;
-    }
-
-    /**
-     * Returns a delegated <code>Runnable</code> task for
-     * this <code>SSLEngine</code>.
-     */
-    synchronized public Runnable getDelegatedTask() {
-        if (handshaker != null) {
-            return handshaker.getTask();
-        }
-        return null;
-    }
-
-
-    //
-    // EXCEPTION AND ALERT HANDLING
-    //
-
-    /*
-     * Send a warning alert.
-     */
-    void warning(byte description) {
-        sendAlert(Alerts.alert_warning, description);
-    }
-
-    synchronized void fatal(byte description, String diagnostic)
-            throws SSLException {
-        fatal(description, diagnostic, null);
-    }
-
-    synchronized void fatal(byte description, Throwable cause)
-            throws SSLException {
-        fatal(description, null, cause);
-    }
-
-    /*
-     * We've got a fatal error here, so start the shutdown process.
-     *
-     * Because of the way the code was written, we have some code
-     * calling fatal directly when the "description" is known
-     * and some throwing Exceptions which are then caught by higher
-     * levels which then call here.  This code needs to determine
-     * if one of the lower levels has already started the process.
-     *
-     * We won't worry about Error's, if we have one of those,
-     * we're in worse trouble.  Note:  the networking code doesn't
-     * deal with Errors either.
-     */
-    synchronized void fatal(byte description, String diagnostic,
-            Throwable cause) throws SSLException {
-
-        /*
-         * If we have no further information, make a general-purpose
-         * message for folks to see.  We generally have one or the other.
-         */
-        if (diagnostic == null) {
-            diagnostic = "General SSLEngine problem";
-        }
-        if (cause == null) {
-            cause = Alerts.getSSLException(description, cause, diagnostic);
-        }
-
-        /*
-         * If we've already shutdown because of an error,
-         * there is nothing we can do except rethrow the exception.
-         *
-         * Most exceptions seen here will be SSLExceptions.
-         * We may find the occasional Exception which hasn't been
-         * converted to a SSLException, so we'll do it here.
-         */
-        if (closeReason != null) {
-            if ((debug != null) && Debug.isOn("ssl")) {
-                System.out.println(threadName() +
-                    ", fatal: engine already closed.  Rethrowing " +
-                    cause.toString());
-            }
-            if (cause instanceof RuntimeException) {
-                throw (RuntimeException)cause;
-            } else if (cause instanceof SSLException) {
-                throw (SSLException)cause;
-            } else if (cause instanceof Exception) {
-                SSLException ssle = new SSLException(
-                    "fatal SSLEngine condition");
-                ssle.initCause(cause);
-                throw ssle;
-            }
-        }
-
-        if ((debug != null) && Debug.isOn("ssl")) {
-            System.out.println(threadName()
-                        + ", fatal error: " + description +
-                        ": " + diagnostic + "\n" + cause.toString());
-        }
-
-        /*
-         * Ok, this engine's going down.
-         */
-        int oldState = connectionState;
-        connectionState = cs_ERROR;
-
-        inboundDone = true;
-
-        sess.invalidate();
-        if (handshakeSession != null) {
-            handshakeSession.invalidate();
-        }
-
-        /*
-         * If we haven't even started handshaking yet, no need
-         * to generate the fatal close alert.
-         */
-        if (oldState != cs_START) {
-            sendAlert(Alerts.alert_fatal, description);
-        }
-
-        if (cause instanceof SSLException) { // only true if != null
-            closeReason = (SSLException)cause;
-        } else {
-            /*
-             * Including RuntimeExceptions, but we'll throw those
-             * down below.  The closeReason isn't used again,
-             * except for null checks.
-             */
-            closeReason =
-                Alerts.getSSLException(description, cause, diagnostic);
-        }
-
-        writer.closeOutbound();
-
-        connectionState = cs_CLOSED;
-
-        // See comment in changeReadCiphers()
-        readCipher.dispose();
-        writeCipher.dispose();
-
-        if (cause instanceof RuntimeException) {
-            throw (RuntimeException)cause;
-        } else {
-            throw closeReason;
-        }
-    }
-
-    /*
-     * Process an incoming alert ... caller must already have synchronized
-     * access to "this".
-     */
-    private void recvAlert() throws IOException {
-        byte level = (byte)inputRecord.read();
-        byte description = (byte)inputRecord.read();
-        if (description == -1) { // check for short message
-            fatal(Alerts.alert_illegal_parameter, "Short alert message");
-        }
-
-        if (debug != null && (Debug.isOn("record") ||
-                Debug.isOn("handshake"))) {
-            synchronized (System.out) {
-                System.out.print(threadName());
-                System.out.print(", RECV " + protocolVersion + " ALERT:  ");
-                if (level == Alerts.alert_fatal) {
-                    System.out.print("fatal, ");
-                } else if (level == Alerts.alert_warning) {
-                    System.out.print("warning, ");
-                } else {
-                    System.out.print("<level " + (0x0ff & level) + ">, ");
-                }
-                System.out.println(Alerts.alertDescription(description));
-            }
-        }
-
-        if (level == Alerts.alert_warning) {
-            if (description == Alerts.alert_close_notify) {
-                if (connectionState == cs_HANDSHAKE) {
-                    fatal(Alerts.alert_unexpected_message,
-                                "Received close_notify during handshake");
-                } else {
-                    recvCN = true;
-                    closeInboundInternal();  // reply to close
-                }
-            } else {
-
-                //
-                // The other legal warnings relate to certificates,
-                // e.g. no_certificate, bad_certificate, etc; these
-                // are important to the handshaking code, which can
-                // also handle illegal protocol alerts if needed.
-                //
-                if (handshaker != null) {
-                    handshaker.handshakeAlert(description);
-                }
-            }
-        } else { // fatal or unknown level
-            String reason = "Received fatal alert: "
-                + Alerts.alertDescription(description);
-            if (closeReason == null) {
-                closeReason = Alerts.getSSLException(description, reason);
-            }
-            fatal(Alerts.alert_unexpected_message, reason);
-        }
-    }
-
-
-    /*
-     * Emit alerts.  Caller must have synchronized with "this".
-     */
-    private void sendAlert(byte level, byte description) {
-        // the connectionState cannot be cs_START
-        if (connectionState >= cs_CLOSED) {
-            return;
-        }
-
-        // For initial handshaking, don't send alert message to peer if
-        // handshaker has not started.
-        if (connectionState == cs_HANDSHAKE &&
-            (handshaker == null || !handshaker.started())) {
-            return;
-        }
-
-        EngineOutputRecord r = new EngineOutputRecord(Record.ct_alert, this);
-        r.setVersion(protocolVersion);
-
-        boolean useDebug = debug != null && Debug.isOn("ssl");
-        if (useDebug) {
-            synchronized (System.out) {
-                System.out.print(threadName());
-                System.out.print(", SEND " + protocolVersion + " ALERT:  ");
-                if (level == Alerts.alert_fatal) {
-                    System.out.print("fatal, ");
-                } else if (level == Alerts.alert_warning) {
-                    System.out.print("warning, ");
-                } else {
-                    System.out.print("<level = " + (0x0ff & level) + ">, ");
-                }
-                System.out.println("description = "
-                        + Alerts.alertDescription(description));
-            }
-        }
-
-        r.write(level);
-        r.write(description);
-        try {
-            writeRecord(r);
-        } catch (IOException e) {
-            if (useDebug) {
-                System.out.println(threadName() +
-                    ", Exception sending alert: " + e);
-            }
-        }
-    }
-
-
-    //
-    // VARIOUS OTHER METHODS (COMMON TO SSLSocket)
-    //
-
-
-    /**
-     * Controls whether new connections may cause creation of new SSL
-     * sessions.
-     *
-     * As long as handshaking has not started, we can change
-     * whether we enable session creations.  Otherwise,
-     * we will need to wait for the next handshake.
-     */
-    synchronized public void setEnableSessionCreation(boolean flag) {
-        enableSessionCreation = flag;
-
-        if ((handshaker != null) && !handshaker.activated()) {
-            handshaker.setEnableSessionCreation(enableSessionCreation);
-        }
-    }
-
-    /**
-     * Returns true if new connections may cause creation of new SSL
-     * sessions.
-     */
-    synchronized public boolean getEnableSessionCreation() {
-        return enableSessionCreation;
-    }
-
-
-    /**
-     * Sets the flag controlling whether a server mode engine
-     * *REQUIRES* SSL client authentication.
-     *
-     * As long as handshaking has not started, we can change
-     * whether client authentication is needed.  Otherwise,
-     * we will need to wait for the next handshake.
-     */
-    synchronized public void setNeedClientAuth(boolean flag) {
-        doClientAuth = (flag ?
-            SSLEngineImpl.clauth_required : SSLEngineImpl.clauth_none);
-
-        if ((handshaker != null) &&
-                (handshaker instanceof ServerHandshaker) &&
-                !handshaker.activated()) {
-            ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
-        }
-    }
-
-    synchronized public boolean getNeedClientAuth() {
-        return (doClientAuth == SSLEngineImpl.clauth_required);
-    }
-
-    /**
-     * Sets the flag controlling whether a server mode engine
-     * *REQUESTS* SSL client authentication.
-     *
-     * As long as handshaking has not started, we can change
-     * whether client authentication is requested.  Otherwise,
-     * we will need to wait for the next handshake.
-     */
-    synchronized public void setWantClientAuth(boolean flag) {
-        doClientAuth = (flag ?
-            SSLEngineImpl.clauth_requested : SSLEngineImpl.clauth_none);
-
-        if ((handshaker != null) &&
-                (handshaker instanceof ServerHandshaker) &&
-                !handshaker.activated()) {
-            ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
-        }
-    }
-
-    synchronized public boolean getWantClientAuth() {
-        return (doClientAuth == SSLEngineImpl.clauth_requested);
-    }
-
-
-    /**
-     * Sets the flag controlling whether the engine is in SSL
-     * client or server mode.  Must be called before any SSL
-     * traffic has started.
-     */
-    synchronized public void setUseClientMode(boolean flag) {
-        switch (connectionState) {
-
-        case cs_START:
-            /*
-             * If we need to change the engine mode and the enabled
-             * protocols haven't specifically been set by the user,
-             * change them to the corresponding default ones.
-             */
-            if (roleIsServer != (!flag) &&
-                    sslContext.isDefaultProtocolList(enabledProtocols)) {
-                enabledProtocols = sslContext.getDefaultProtocolList(!flag);
-            }
-
-            roleIsServer = !flag;
-            serverModeSet = true;
-            break;
-
-        case cs_HANDSHAKE:
-            /*
-             * If we have a handshaker, but haven't started
-             * SSL traffic, we can throw away our current
-             * handshaker, and start from scratch.  Don't
-             * need to call doneConnect() again, we already
-             * have the streams.
-             */
-            assert(handshaker != null);
-            if (!handshaker.activated()) {
-                /*
-                 * If we need to change the engine mode and the enabled
-                 * protocols haven't specifically been set by the user,
-                 * change them to the corresponding default ones.
-                 */
-                if (roleIsServer != (!flag) &&
-                        sslContext.isDefaultProtocolList(enabledProtocols)) {
-                    enabledProtocols = sslContext.getDefaultProtocolList(!flag);
-                }
-
-                roleIsServer = !flag;
-                connectionState = cs_START;
-                initHandshaker();
-                break;
-            }
-
-            // If handshake has started, that's an error.  Fall through...
-
-        default:
-            if (debug != null && Debug.isOn("ssl")) {
-                System.out.println(threadName() +
-                    ", setUseClientMode() invoked in state = " +
-                    connectionState);
-            }
-
-            /*
-             * We can let them continue if they catch this correctly,
-             * we don't need to shut this down.
-             */
-            throw new IllegalArgumentException(
-                "Cannot change mode after SSL traffic has started");
-        }
-    }
-
-    synchronized public boolean getUseClientMode() {
-        return !roleIsServer;
-    }
-
-
-    /**
-     * Returns the names of the cipher suites which could be enabled for use
-     * on an SSL connection.  Normally, only a subset of these will actually
-     * be enabled by default, since this list may include cipher suites which
-     * do not support the mutual authentication of servers and clients, or
-     * which do not protect data confidentiality.  Servers may also need
-     * certain kinds of certificates to use certain cipher suites.
-     *
-     * @return an array of cipher suite names
-     */
-    public String[] getSupportedCipherSuites() {
-        return sslContext.getSupportedCipherSuiteList().toStringArray();
-    }
-
-    /**
-     * Controls which particular cipher suites are enabled for use on
-     * this connection.  The cipher suites must have been listed by
-     * getCipherSuites() as being supported.  Even if a suite has been
-     * enabled, it might never be used if no peer supports it or the
-     * requisite certificates (and private keys) are not available.
-     *
-     * @param suites Names of all the cipher suites to enable.
-     */
-    synchronized public void setEnabledCipherSuites(String[] suites) {
-        enabledCipherSuites = new CipherSuiteList(suites);
-        if ((handshaker != null) && !handshaker.activated()) {
-            handshaker.setEnabledCipherSuites(enabledCipherSuites);
-        }
-    }
-
-    /**
-     * Returns the names of the SSL cipher suites which are currently enabled
-     * for use on this connection.  When an SSL engine is first created,
-     * all enabled cipher suites <em>(a)</em> protect data confidentiality,
-     * by traffic encryption, and <em>(b)</em> can mutually authenticate
-     * both clients and servers.  Thus, in some environments, this value
-     * might be empty.
-     *
-     * @return an array of cipher suite names
-     */
-    synchronized public String[] getEnabledCipherSuites() {
-        return enabledCipherSuites.toStringArray();
-    }
-
-
-    /**
-     * Returns the protocols that are supported by this implementation.
-     * A subset of the supported protocols may be enabled for this connection
-     * @return an array of protocol names.
-     */
-    public String[] getSupportedProtocols() {
-        return sslContext.getSuportedProtocolList().toStringArray();
-    }
-
-    /**
-     * Controls which protocols are enabled for use on
-     * this connection.  The protocols must have been listed by
-     * getSupportedProtocols() as being supported.
-     *
-     * @param protocols protocols to enable.
-     * @exception IllegalArgumentException when one of the protocols
-     *  named by the parameter is not supported.
-     */
-    synchronized public void setEnabledProtocols(String[] protocols) {
-        enabledProtocols = new ProtocolList(protocols);
-        if ((handshaker != null) && !handshaker.activated()) {
-            handshaker.setEnabledProtocols(enabledProtocols);
-        }
-    }
-
-    synchronized public String[] getEnabledProtocols() {
-        return enabledProtocols.toStringArray();
-    }
-
-    /**
-     * Returns the SSLParameters in effect for this SSLEngine.
-     */
-    synchronized public SSLParameters getSSLParameters() {
-        SSLParameters params = super.getSSLParameters();
-
-        // the super implementation does not handle the following parameters
-        params.setEndpointIdentificationAlgorithm(identificationProtocol);
-        params.setAlgorithmConstraints(algorithmConstraints);
-
-        return params;
-    }
-
-    /**
-     * Applies SSLParameters to this engine.
-     */
-    synchronized public void setSSLParameters(SSLParameters params) {
-        super.setSSLParameters(params);
-
-        // the super implementation does not handle the following parameters
-        identificationProtocol = params.getEndpointIdentificationAlgorithm();
-        algorithmConstraints = params.getAlgorithmConstraints();
-        if ((handshaker != null) && !handshaker.started()) {
-            handshaker.setIdentificationProtocol(identificationProtocol);
-            handshaker.setAlgorithmConstraints(algorithmConstraints);
-        }
-    }
-
-    /**
-     * Return the name of the current thread. Utility method.
-     */
-    private static String threadName() {
-        return Thread.currentThread().getName();
-    }
-
-    /**
-     * Returns a printable representation of this end of the connection.
-     */
-    public String toString() {
-        StringBuilder retval = new StringBuilder(80);
-
-        retval.append(Integer.toHexString(hashCode()));
-        retval.append("[");
-        retval.append("SSLEngine[hostname=");
-        String host = getPeerHost();
-        retval.append((host == null) ? "null" : host);
-        retval.append(" port=");
-        retval.append(Integer.toString(getPeerPort()));
-        retval.append("] ");
-        retval.append(getSession().getCipherSuite());
-        retval.append("]");
-
-        return retval.toString();
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/SSLServerSocketFactoryImpl.java b/ojluni/src/main/java/sun/security/ssl/SSLServerSocketFactoryImpl.java
deleted file mode 100755
index 2b99129..0000000
--- a/ojluni/src/main/java/sun/security/ssl/SSLServerSocketFactoryImpl.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-
-import javax.net.ssl.SSLServerSocketFactory;
-
-/**
- * This class creates SSL server sockets.
- *
- * @author David Brownell
- */
-final
-public class SSLServerSocketFactoryImpl extends SSLServerSocketFactory
-{
-    private static final int DEFAULT_BACKLOG = 50;
-    private SSLContextImpl context;
-
-
-    /**
-     * Constructor used to instantiate the default factory. This method is
-     * only called if the old "ssl.ServerSocketFactory.provider" property in the
-     * java.security file is set.
-     */
-    public SSLServerSocketFactoryImpl() throws Exception {
-        this.context = SSLContextImpl.DefaultSSLContext.getDefaultImpl();
-    }
-
-    /**
-     * Called from SSLContextImpl's getSSLServerSocketFactory().
-     */
-    SSLServerSocketFactoryImpl (SSLContextImpl context)
-    {
-        this.context = context;
-    }
-
-    /**
-     * Returns an unbound server socket.
-     *
-     * @return the unbound socket
-     * @throws IOException if the socket cannot be created
-     * @see java.net.Socket#bind(java.net.SocketAddress)
-     */
-    public ServerSocket createServerSocket() throws IOException {
-        return new SSLServerSocketImpl(context);
-    }
-
-    public ServerSocket createServerSocket (int port)
-    throws IOException
-    {
-        return new SSLServerSocketImpl (port, DEFAULT_BACKLOG, context);
-    }
-
-
-    public ServerSocket createServerSocket (int port, int backlog)
-    throws IOException
-    {
-        return new SSLServerSocketImpl (port, backlog, context);
-    }
-
-    public ServerSocket
-    createServerSocket (int port, int backlog, InetAddress ifAddress)
-    throws IOException
-    {
-        return new SSLServerSocketImpl (port, backlog, ifAddress, context);
-    }
-
-    /**
-     * Returns the subset of the supported cipher suites which are
-     * enabled by default.  These cipher suites all provide a minimum
-     * quality of service whereby the server authenticates itself
-     * (preventing person-in-the-middle attacks) and where traffic
-     * is encrypted to provide confidentiality.
-     */
-    public String[] getDefaultCipherSuites() {
-        return context.getDefaultCipherSuiteList(true).toStringArray();
-    }
-
-    /**
-     * Returns the names of the cipher suites which could be enabled for use
-     * on an SSL connection.  Normally, only a subset of these will actually
-     * be enabled by default, since this list may include cipher suites which
-     * do not support the mutual authentication of servers and clients, or
-     * which do not protect data confidentiality.  Servers may also need
-     * certain kinds of certificates to use certain cipher suites.
-     *
-     * @return an array of cipher suite names
-     */
-    public String[] getSupportedCipherSuites() {
-        return context.getSupportedCipherSuiteList().toStringArray();
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/SSLServerSocketImpl.java b/ojluni/src/main/java/sun/security/ssl/SSLServerSocketImpl.java
deleted file mode 100755
index c2098c1..0000000
--- a/ojluni/src/main/java/sun/security/ssl/SSLServerSocketImpl.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.ServerSocket;
-
-import java.security.AlgorithmConstraints;
-
-import java.util.*;
-
-import javax.net.ServerSocketFactory;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLParameters;
-
-
-/**
- * This class provides a simple way for servers to support conventional
- * use of the Secure Sockets Layer (SSL).  Application code uses an
- * SSLServerSocketImpl exactly like it uses a regular TCP ServerSocket; the
- * difference is that the connections established are secured using SSL.
- *
- * <P> Also, the constructors take an explicit authentication context
- * parameter, giving flexibility with respect to how the server socket
- * authenticates itself.  That policy flexibility is not exposed through
- * the standard SSLServerSocketFactory API.
- *
- * <P> System security defaults prevent server sockets from accepting
- * connections if they the authentication context has not been given
- * a certificate chain and its matching private key.  If the clients
- * of your application support "anonymous" cipher suites, you may be
- * able to configure a server socket to accept those suites.
- *
- * @see SSLSocketImpl
- * @see SSLServerSocketFactoryImpl
- *
- * @author David Brownell
- */
-final
-class SSLServerSocketImpl extends SSLServerSocket
-{
-    private SSLContextImpl      sslContext;
-
-    /* Do newly accepted connections require clients to authenticate? */
-    private byte                doClientAuth = SSLEngineImpl.clauth_none;
-
-    /* Do new connections created here use the "server" mode of SSL? */
-    private boolean             useServerMode = true;
-
-    /* Can new connections created establish new sessions? */
-    private boolean             enableSessionCreation = true;
-
-    /* what cipher suites to use by default */
-    private CipherSuiteList     enabledCipherSuites = null;
-
-    /* which protocol to use by default */
-    private ProtocolList        enabledProtocols = null;
-
-    /* could enabledCipherSuites ever complete handshaking? */
-    private boolean             checkedEnabled = false;
-
-    // the endpoint identification protocol to use by default
-    private String              identificationProtocol = null;
-
-    // The cryptographic algorithm constraints
-    private AlgorithmConstraints    algorithmConstraints = null;
-
-    /**
-     * Create an SSL server socket on a port, using a non-default
-     * authentication context and a specified connection backlog.
-     *
-     * @param port the port on which to listen
-     * @param backlog how many connections may be pending before
-     *          the system should start rejecting new requests
-     * @param context authentication context for this server
-     */
-    SSLServerSocketImpl(int port, int backlog, SSLContextImpl context)
-    throws IOException, SSLException
-    {
-        super(port, backlog);
-        initServer(context);
-    }
-
-
-    /**
-     * Create an SSL server socket on a port, using a specified
-     * authentication context and a specified backlog of connections
-     * as well as a particular specified network interface.  This
-     * constructor is used on multihomed hosts, such as those used
-     * for firewalls or as routers, to control through which interface
-     * a network service is provided.
-     *
-     * @param port the port on which to listen
-     * @param backlog how many connections may be pending before
-     *          the system should start rejecting new requests
-     * @param address the address of the network interface through
-     *          which connections will be accepted
-     * @param context authentication context for this server
-     */
-    SSLServerSocketImpl(
-        int             port,
-        int             backlog,
-        InetAddress     address,
-        SSLContextImpl  context)
-        throws IOException
-    {
-        super(port, backlog, address);
-        initServer(context);
-    }
-
-
-    /**
-     * Creates an unbound server socket.
-     */
-    SSLServerSocketImpl(SSLContextImpl context) throws IOException {
-        super();
-        initServer(context);
-    }
-
-
-    /**
-     * Initializes the server socket.
-     */
-    private void initServer(SSLContextImpl context) throws SSLException {
-        if (context == null) {
-            throw new SSLException("No Authentication context given");
-        }
-        sslContext = context;
-        enabledCipherSuites = sslContext.getDefaultCipherSuiteList(true);
-        enabledProtocols = sslContext.getDefaultProtocolList(true);
-    }
-
-    /**
-     * Returns the names of the cipher suites which could be enabled for use
-     * on an SSL connection.  Normally, only a subset of these will actually
-     * be enabled by default, since this list may include cipher suites which
-     * do not support the mutual authentication of servers and clients, or
-     * which do not protect data confidentiality.  Servers may also need
-     * certain kinds of certificates to use certain cipher suites.
-     *
-     * @return an array of cipher suite names
-     */
-    public String[] getSupportedCipherSuites() {
-        return sslContext.getSupportedCipherSuiteList().toStringArray();
-    }
-
-    /**
-     * Returns the list of cipher suites which are currently enabled
-     * for use by newly accepted connections.  A null return indicates
-     * that the system defaults are in effect.
-     */
-    synchronized public String[] getEnabledCipherSuites() {
-        return enabledCipherSuites.toStringArray();
-    }
-
-    /**
-     * Controls which particular SSL cipher suites are enabled for use
-     * by accepted connections.
-     *
-     * @param suites Names of all the cipher suites to enable; null
-     *  means to accept system defaults.
-     */
-    synchronized public void setEnabledCipherSuites(String[] suites) {
-        enabledCipherSuites = new CipherSuiteList(suites);
-        checkedEnabled = false;
-    }
-
-    public String[] getSupportedProtocols() {
-        return sslContext.getSuportedProtocolList().toStringArray();
-    }
-
-    /**
-     * Controls which protocols are enabled for use.
-     * The protocols must have been listed by
-     * getSupportedProtocols() as being supported.
-     *
-     * @param protocols protocols to enable.
-     * @exception IllegalArgumentException when one of the protocols
-     *  named by the parameter is not supported.
-     */
-    synchronized public void setEnabledProtocols(String[] protocols) {
-        enabledProtocols = new ProtocolList(protocols);
-    }
-
-    synchronized public String[] getEnabledProtocols() {
-        return enabledProtocols.toStringArray();
-    }
-
-    /**
-     * Controls whether the connections which are accepted must include
-     * client authentication.
-     */
-    public void setNeedClientAuth(boolean flag) {
-        doClientAuth = (flag ?
-            SSLEngineImpl.clauth_required : SSLEngineImpl.clauth_none);
-    }
-
-    public boolean getNeedClientAuth() {
-        return (doClientAuth == SSLEngineImpl.clauth_required);
-    }
-
-    /**
-     * Controls whether the connections which are accepted should request
-     * client authentication.
-     */
-    public void setWantClientAuth(boolean flag) {
-        doClientAuth = (flag ?
-            SSLEngineImpl.clauth_requested : SSLEngineImpl.clauth_none);
-    }
-
-    public boolean getWantClientAuth() {
-        return (doClientAuth == SSLEngineImpl.clauth_requested);
-    }
-
-    /**
-     * Makes the returned sockets act in SSL "client" mode, not the usual
-     * server mode.  The canonical example of why this is needed is for
-     * FTP clients, which accept connections from servers and should be
-     * rejoining the already-negotiated SSL connection.
-     */
-    public void setUseClientMode(boolean flag) {
-        /*
-         * If we need to change the socket mode and the enabled
-         * protocols haven't specifically been set by the user,
-         * change them to the corresponding default ones.
-         */
-        if (useServerMode != (!flag) &&
-                sslContext.isDefaultProtocolList(enabledProtocols)) {
-            enabledProtocols = sslContext.getDefaultProtocolList(!flag);
-        }
-
-        useServerMode = !flag;
-    }
-
-    public boolean getUseClientMode() {
-        return !useServerMode;
-    }
-
-
-    /**
-     * Controls whether new connections may cause creation of new SSL
-     * sessions.
-     */
-    public void setEnableSessionCreation(boolean flag) {
-        enableSessionCreation = flag;
-    }
-
-    /**
-     * Returns true if new connections may cause creation of new SSL
-     * sessions.
-     */
-    public boolean getEnableSessionCreation() {
-        return enableSessionCreation;
-    }
-
-    /**
-     * Returns the SSLParameters in effect for newly accepted connections.
-     */
-    synchronized public SSLParameters getSSLParameters() {
-        SSLParameters params = super.getSSLParameters();
-
-        // the super implementation does not handle the following parameters
-        params.setEndpointIdentificationAlgorithm(identificationProtocol);
-        params.setAlgorithmConstraints(algorithmConstraints);
-
-        return params;
-    }
-
-    /**
-     * Applies SSLParameters to newly accepted connections.
-     */
-    synchronized public void setSSLParameters(SSLParameters params) {
-        super.setSSLParameters(params);
-
-        // the super implementation does not handle the following parameters
-        identificationProtocol = params.getEndpointIdentificationAlgorithm();
-        algorithmConstraints = params.getAlgorithmConstraints();
-    }
-
-    /**
-     * Accept a new SSL connection.  This server identifies itself with
-     * information provided in the authentication context which was
-     * presented during construction.
-     */
-    public Socket accept() throws IOException {
-        SSLSocketImpl s = new SSLSocketImpl(sslContext, useServerMode,
-            enabledCipherSuites, doClientAuth, enableSessionCreation,
-            enabledProtocols, identificationProtocol, algorithmConstraints);
-
-        implAccept(s);
-        s.doneConnect();
-        return s;
-    }
-
-    /**
-     * Provides a brief description of this SSL socket.
-     */
-    public String toString() {
-        return "[SSL: "+ super.toString() + "]";
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/SSLSessionContextImpl.java b/ojluni/src/main/java/sun/security/ssl/SSLSessionContextImpl.java
deleted file mode 100755
index 756a48e..0000000
--- a/ojluni/src/main/java/sun/security/ssl/SSLSessionContextImpl.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.util.Enumeration;
-import java.util.Vector;
-import java.util.Locale;
-
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSessionContext;
-
-import sun.security.util.Cache;
-
-
-final class SSLSessionContextImpl implements SSLSessionContext {
-    private Cache<SessionId, SSLSessionImpl> sessionCache;
-                                        // session cache, session id as key
-    private Cache<String, SSLSessionImpl> sessionHostPortCache;
-                                        // session cache, "host:port" as key
-    private int cacheLimit;             // the max cache size
-    private int timeout;                // timeout in seconds
-
-    // package private
-    SSLSessionContextImpl() {
-        cacheLimit = getDefaultCacheLimit();    // default cache size
-        timeout = 86400;                        // default, 24 hours
-
-        // use soft reference
-        sessionCache = Cache.newSoftMemoryCache(cacheLimit, timeout);
-        sessionHostPortCache = Cache.newSoftMemoryCache(cacheLimit, timeout);
-    }
-
-    /**
-     * Returns the <code>SSLSession</code> bound to the specified session id.
-     */
-    @Override
-    public SSLSession getSession(byte[] sessionId) {
-        if (sessionId == null) {
-            throw new NullPointerException("session id cannot be null");
-        }
-
-        SSLSessionImpl sess = sessionCache.get(new SessionId(sessionId));
-        if (!isTimedout(sess)) {
-            return sess;
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns an enumeration of the active SSL sessions.
-     */
-    @Override
-    public Enumeration<byte[]> getIds() {
-        SessionCacheVisitor scVisitor = new SessionCacheVisitor();
-        sessionCache.accept(scVisitor);
-
-        return scVisitor.getSessionIds();
-    }
-
-    /**
-     * Sets the timeout limit for cached <code>SSLSession</code> objects
-     *
-     * Note that after reset the timeout, the cached session before
-     * should be timed within the shorter one of the old timeout and the
-     * new timeout.
-     */
-    @Override
-    public void setSessionTimeout(int seconds)
-                 throws IllegalArgumentException {
-        if (seconds < 0) {
-            throw new IllegalArgumentException();
-        }
-
-        if (timeout != seconds) {
-            sessionCache.setTimeout(seconds);
-            sessionHostPortCache.setTimeout(seconds);
-            timeout = seconds;
-        }
-    }
-
-    /**
-     * Gets the timeout limit for cached <code>SSLSession</code> objects
-     */
-    @Override
-    public int getSessionTimeout() {
-        return timeout;
-    }
-
-    /**
-     * Sets the size of the cache used for storing
-     * <code>SSLSession</code> objects.
-     */
-    @Override
-    public void setSessionCacheSize(int size)
-                 throws IllegalArgumentException {
-        if (size < 0)
-            throw new IllegalArgumentException();
-
-        if (cacheLimit != size) {
-            sessionCache.setCapacity(size);
-            sessionHostPortCache.setCapacity(size);
-            cacheLimit = size;
-        }
-    }
-
-    /**
-     * Gets the size of the cache used for storing
-     * <code>SSLSession</code> objects.
-     */
-    @Override
-    public int getSessionCacheSize() {
-        return cacheLimit;
-    }
-
-
-    // package-private method, used ONLY by ServerHandshaker
-    SSLSessionImpl get(byte[] id) {
-        return (SSLSessionImpl)getSession(id);
-    }
-
-    // package-private method, used ONLY by ClientHandshaker
-    SSLSessionImpl get(String hostname, int port) {
-        /*
-         * If no session caching info is available, we won't
-         * get one, so exit before doing a lookup.
-         */
-        if (hostname == null && port == -1) {
-            return null;
-        }
-
-        SSLSessionImpl sess = sessionHostPortCache.get(getKey(hostname, port));
-        if (!isTimedout(sess)) {
-            return sess;
-        }
-
-        return null;
-    }
-
-    private String getKey(String hostname, int port) {
-        return (hostname + ":" +
-            String.valueOf(port)).toLowerCase(Locale.ENGLISH);
-    }
-
-    // cache a SSLSession
-    //
-    // In SunJSSE implementation, a session is created while getting a
-    // client hello or a server hello message, and cached while the
-    // handshaking finished.
-    // Here we time the session from the time it cached instead of the
-    // time it created, which is a little longer than the expected. So
-    // please do check isTimedout() while getting entry from the cache.
-    void put(SSLSessionImpl s) {
-        sessionCache.put(s.getSessionId(), s);
-
-        // If no hostname/port info is available, don't add this one.
-        if ((s.getPeerHost() != null) && (s.getPeerPort() != -1)) {
-            sessionHostPortCache.put(
-                getKey(s.getPeerHost(), s.getPeerPort()), s);
-        }
-
-        s.setContext(this);
-    }
-
-    // package-private method, remove a cached SSLSession
-    void remove(SessionId key) {
-        SSLSessionImpl s = sessionCache.get(key);
-        if (s != null) {
-            sessionCache.remove(key);
-            sessionHostPortCache.remove(
-                        getKey(s.getPeerHost(), s.getPeerPort()));
-        }
-    }
-
-    private int getDefaultCacheLimit() {
-        int cacheLimit = 0;
-        try {
-        String s = java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedAction<String>() {
-                @Override
-                public String run() {
-                    return System.getProperty(
-                        "javax.net.ssl.sessionCacheSize");
-                }
-            });
-            cacheLimit = (s != null) ? Integer.parseInt(s) : 0;
-        } catch (Exception e) {
-        }
-
-        return (cacheLimit > 0) ? cacheLimit : 0;
-    }
-
-    boolean isTimedout(SSLSession sess) {
-        if (timeout == 0) {
-            return false;
-        }
-
-        if ((sess != null) && ((sess.getCreationTime() + timeout * 1000L)
-                                        <= (System.currentTimeMillis()))) {
-            sess.invalidate();
-            return true;
-        }
-
-        return false;
-    }
-
-    final class SessionCacheVisitor
-            implements Cache.CacheVisitor<SessionId, SSLSessionImpl> {
-        Vector<byte[]> ids = null;
-
-        // public void visit(java.util.Map<K,V> map) {}
-        @Override
-        public void visit(java.util.Map<SessionId, SSLSessionImpl> map) {
-            ids = new Vector<>(map.size());
-
-            for (SessionId key : map.keySet()) {
-                SSLSessionImpl value = map.get(key);
-                if (!isTimedout(value)) {
-                    ids.addElement(key.getId());
-                }
-            }
-        }
-
-        public Enumeration<byte[]> getSessionIds() {
-            return  ids != null ? ids.elements() :
-                                  new Vector<byte[]>().elements();
-        }
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/SSLSessionImpl.java b/ojluni/src/main/java/sun/security/ssl/SSLSessionImpl.java
deleted file mode 100755
index 110fc9c..0000000
--- a/ojluni/src/main/java/sun/security/ssl/SSLSessionImpl.java
+++ /dev/null
@@ -1,832 +0,0 @@
-/*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.net.*;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Vector;
-import java.util.Arrays;
-import java.util.Collection;
-
-import java.security.Principal;
-import java.security.PrivateKey;
-import java.security.SecureRandom;
-import java.security.cert.X509Certificate;
-import java.security.cert.CertificateEncodingException;
-
-import javax.crypto.SecretKey;
-
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSessionContext;
-import javax.net.ssl.SSLSessionBindingListener;
-import javax.net.ssl.SSLSessionBindingEvent;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLPermission;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.ExtendedSSLSession;
-
-import javax.security.auth.x500.X500Principal;
-
-import static sun.security.ssl.CipherSuite.*;
-import static sun.security.ssl.CipherSuite.KeyExchange.*;
-
-/**
- * Implements the SSL session interface, and exposes the session context
- * which is maintained by SSL servers.
- *
- * <P> Servers have the ability to manage the sessions associated with
- * their authentication context(s).  They can do this by enumerating the
- * IDs of the sessions which are cached, examining those sessions, and then
- * perhaps invalidating a given session so that it can't be used again.
- * If servers do not explicitly manage the cache, sessions will linger
- * until memory is low enough that the runtime environment purges cache
- * entries automatically to reclaim space.
- *
- * <P><em> The only reason this class is not package-private is that
- * there's no other public way to get at the server session context which
- * is associated with any given authentication context. </em>
- *
- * @author David Brownell
- */
-final class SSLSessionImpl extends ExtendedSSLSession {
-
-    /*
-     * we only really need a single null session
-     */
-    static final SSLSessionImpl         nullSession = new SSLSessionImpl();
-
-    // compression methods
-    private static final byte           compression_null = 0;
-
-    /*
-     * The state of a single session, as described in section 7.1
-     * of the SSLv3 spec.
-     */
-    private final ProtocolVersion       protocolVersion;
-    private final SessionId             sessionId;
-    private X509Certificate[]   peerCerts;
-    private byte                compressionMethod;
-    private CipherSuite         cipherSuite;
-    private SecretKey           masterSecret;
-
-    /*
-     * Information not part of the SSLv3 protocol spec, but used
-     * to support session management policies.
-     */
-    private final long          creationTime = System.currentTimeMillis();
-    private long                lastUsedTime = 0;
-    private final String        host;
-    private final int           port;
-    private SSLSessionContextImpl       context;
-    private int                 sessionCount;
-    private boolean             invalidated;
-    private X509Certificate[]   localCerts;
-    private PrivateKey          localPrivateKey;
-    private String[]            localSupportedSignAlgs;
-    private String[]            peerSupportedSignAlgs;
-
-    // Principals for non-certificate based cipher suites
-    private Principal peerPrincipal;
-    private Principal localPrincipal;
-
-    /*
-     * We count session creations, eventually for statistical data but
-     * also since counters make shorter debugging IDs than the big ones
-     * we use in the protocol for uniqueness-over-time.
-     */
-    private static volatile int counter = 0;
-
-    /*
-     * Use of session caches is globally enabled/disabled.
-     */
-    private static boolean      defaultRejoinable = true;
-
-    /* Class and subclass dynamic debugging support */
-    private static final Debug debug = Debug.getInstance("ssl");
-
-    /*
-     * Create a new non-rejoinable session, using the default (null)
-     * cipher spec.  This constructor returns a session which could
-     * be used either by a client or by a server, as a connection is
-     * first opened and before handshaking begins.
-     */
-    private SSLSessionImpl() {
-        this(ProtocolVersion.NONE, CipherSuite.C_NULL, null,
-            new SessionId(false, null), null, -1);
-    }
-
-    /*
-     * Create a new session, using a given cipher spec.  This will
-     * be rejoinable if session caching is enabled; the constructor
-     * is intended mostly for use by serves.
-     */
-    SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite,
-            Collection<SignatureAndHashAlgorithm> algorithms,
-            SecureRandom generator, String host, int port) {
-        this(protocolVersion, cipherSuite, algorithms,
-             new SessionId(defaultRejoinable, generator), host, port);
-    }
-
-    /*
-     * Record a new session, using a given cipher spec and session ID.
-     */
-    SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite,
-            Collection<SignatureAndHashAlgorithm> algorithms,
-            SessionId id, String host, int port) {
-        this.protocolVersion = protocolVersion;
-        sessionId = id;
-        peerCerts = null;
-        compressionMethod = compression_null;
-        this.cipherSuite = cipherSuite;
-        masterSecret = null;
-        this.host = host;
-        this.port = port;
-        sessionCount = ++counter;
-        localSupportedSignAlgs =
-            SignatureAndHashAlgorithm.getAlgorithmNames(algorithms);
-
-        if (debug != null && Debug.isOn("session")) {
-            System.out.println("%% Initialized:  " + this);
-        }
-    }
-
-    void setMasterSecret(SecretKey secret) {
-        if (masterSecret == null) {
-            masterSecret = secret;
-        } else {
-            throw new RuntimeException("setMasterSecret() error");
-        }
-    }
-
-    /**
-     * Returns the master secret ... treat with extreme caution!
-     */
-    SecretKey getMasterSecret() {
-        return masterSecret;
-    }
-
-    void setPeerCertificates(X509Certificate[] peer) {
-        if (peerCerts == null) {
-            peerCerts = peer;
-        }
-    }
-
-    void setLocalCertificates(X509Certificate[] local) {
-        localCerts = local;
-    }
-
-    void setLocalPrivateKey(PrivateKey privateKey) {
-        localPrivateKey = privateKey;
-    }
-
-    void setPeerSupportedSignatureAlgorithms(
-            Collection<SignatureAndHashAlgorithm> algorithms) {
-        peerSupportedSignAlgs =
-            SignatureAndHashAlgorithm.getAlgorithmNames(algorithms);
-    }
-
-    /**
-     * Set the peer principal.
-     */
-    void setPeerPrincipal(Principal principal) {
-        if (peerPrincipal == null) {
-            peerPrincipal = principal;
-        }
-    }
-
-    /**
-     * Set the local principal.
-     */
-    void setLocalPrincipal(Principal principal) {
-        localPrincipal = principal;
-    }
-
-    /**
-     * Returns true iff this session may be resumed ... sessions are
-     * usually resumable.  Security policies may suggest otherwise,
-     * for example sessions that haven't been used for a while (say,
-     * a working day) won't be resumable, and sessions might have a
-     * maximum lifetime in any case.
-     */
-    boolean isRejoinable() {
-        return sessionId != null && sessionId.length() != 0 &&
-            !invalidated && isLocalAuthenticationValid();
-    }
-
-    public synchronized boolean isValid() {
-        return isRejoinable();
-    }
-
-    /**
-     * Check if the authentication used when establishing this session
-     * is still valid. Returns true if no authentication was used
-     */
-    boolean isLocalAuthenticationValid() {
-        if (localPrivateKey != null) {
-            try {
-                // if the private key is no longer valid, getAlgorithm()
-                // should throw an exception
-                // (e.g. Smartcard has been removed from the reader)
-                localPrivateKey.getAlgorithm();
-            } catch (Exception e) {
-                invalidate();
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Returns the ID for this session.  The ID is fixed for the
-     * duration of the session; neither it, nor its value, changes.
-     */
-    public byte[] getId() {
-        return sessionId.getId();
-    }
-
-    /**
-     * For server sessions, this returns the set of sessions which
-     * are currently valid in this process.  For client sessions,
-     * this returns null.
-     */
-    public SSLSessionContext getSessionContext() {
-        /*
-         * An interim security policy until we can do something
-         * more specific in 1.2. Only allow trusted code (code which
-         * can set system properties) to get an
-         * SSLSessionContext. This is to limit the ability of code to
-         * look up specific sessions or enumerate over them. Otherwise,
-         * code can only get session objects from successful SSL
-         * connections which implies that they must have had permission
-         * to make the network connection in the first place.
-         */
-        SecurityManager sm;
-        if ((sm = System.getSecurityManager()) != null) {
-            sm.checkPermission(new SSLPermission("getSSLSessionContext"));
-        }
-
-        return context;
-    }
-
-
-    SessionId getSessionId() {
-        return sessionId;
-    }
-
-
-    /**
-     * Returns the cipher spec in use on this session
-     */
-    CipherSuite getSuite() {
-        return cipherSuite;
-    }
-
-    /**
-     * Resets the cipher spec in use on this session
-     */
-    void setSuite(CipherSuite suite) {
-       cipherSuite = suite;
-
-       if (debug != null && Debug.isOn("session")) {
-           System.out.println("%% Negotiating:  " + this);
-       }
-    }
-
-    /**
-     * Returns the name of the cipher suite in use on this session
-     */
-    public String getCipherSuite() {
-        return getSuite().name;
-    }
-
-    ProtocolVersion getProtocolVersion() {
-        return protocolVersion;
-    }
-
-    /**
-     * Returns the standard name of the protocol in use on this session
-     */
-    public String getProtocol() {
-        return getProtocolVersion().name;
-    }
-
-    /**
-     * Returns the compression technique used in this session
-     */
-    byte getCompression() {
-        return compressionMethod;
-    }
-
-    /**
-     * Returns the hashcode for this session
-     */
-    public int hashCode() {
-        return sessionId.hashCode();
-    }
-
-
-    /**
-     * Returns true if sessions have same ids, false otherwise.
-     */
-    public boolean equals(Object obj) {
-
-        if (obj == this) {
-            return true;
-        }
-
-        if (obj instanceof SSLSessionImpl) {
-            SSLSessionImpl sess = (SSLSessionImpl) obj;
-            return (sessionId != null) && (sessionId.equals(
-                        sess.getSessionId()));
-        }
-
-        return false;
-    }
-
-
-    /**
-     * Return the cert chain presented by the peer in the
-     * java.security.cert format.
-     * Note: This method can be used only when using certificate-based
-     * cipher suites; using it with non-certificate-based cipher suites,
-     * such as Kerberos, will throw an SSLPeerUnverifiedException.
-     *
-     * @return array of peer X.509 certs, with the peer's own cert
-     *  first in the chain, and with the "root" CA last.
-     */
-    public java.security.cert.Certificate[] getPeerCertificates()
-            throws SSLPeerUnverifiedException {
-        //
-        // clone to preserve integrity of session ... caller can't
-        // change record of peer identity even by accident, much
-        // less do it intentionally.
-        //
-        if ((cipherSuite.keyExchange == K_KRB5) ||
-            (cipherSuite.keyExchange == K_KRB5_EXPORT)) {
-            throw new SSLPeerUnverifiedException("no certificates expected"
-                        + " for Kerberos cipher suites");
-        }
-        if (peerCerts == null) {
-            throw new SSLPeerUnverifiedException("peer not authenticated");
-        }
-        // Certs are immutable objects, therefore we don't clone them.
-        // But do need to clone the array, so that nothing is inserted
-        // into peerCerts.
-        return (java.security.cert.Certificate[])peerCerts.clone();
-    }
-
-    /**
-     * Return the cert chain presented to the peer in the
-     * java.security.cert format.
-     * Note: This method is useful only when using certificate-based
-     * cipher suites.
-     *
-     * @return array of peer X.509 certs, with the peer's own cert
-     *  first in the chain, and with the "root" CA last.
-     */
-    public java.security.cert.Certificate[] getLocalCertificates() {
-        //
-        // clone to preserve integrity of session ... caller can't
-        // change record of peer identity even by accident, much
-        // less do it intentionally.
-        return (localCerts == null ? null :
-            (java.security.cert.Certificate[])localCerts.clone());
-    }
-
-    /**
-     * Return the cert chain presented by the peer in the
-     * javax.security.cert format.
-     * Note: This method can be used only when using certificate-based
-     * cipher suites; using it with non-certificate-based cipher suites,
-     * such as Kerberos, will throw an SSLPeerUnverifiedException.
-     *
-     * @return array of peer X.509 certs, with the peer's own cert
-     *  first in the chain, and with the "root" CA last.
-     */
-    public javax.security.cert.X509Certificate[] getPeerCertificateChain()
-            throws SSLPeerUnverifiedException {
-        //
-        // clone to preserve integrity of session ... caller can't
-        // change record of peer identity even by accident, much
-        // less do it intentionally.
-        //
-        if ((cipherSuite.keyExchange == K_KRB5) ||
-            (cipherSuite.keyExchange == K_KRB5_EXPORT)) {
-            throw new SSLPeerUnverifiedException("no certificates expected"
-                        + " for Kerberos cipher suites");
-        }
-        if (peerCerts == null) {
-            throw new SSLPeerUnverifiedException("peer not authenticated");
-        }
-        javax.security.cert.X509Certificate[] certs;
-        certs = new javax.security.cert.X509Certificate[peerCerts.length];
-        for (int i = 0; i < peerCerts.length; i++) {
-            byte[] der = null;
-            try {
-                der = peerCerts[i].getEncoded();
-                certs[i] = javax.security.cert.X509Certificate.getInstance(der);
-            } catch (CertificateEncodingException e) {
-                throw new SSLPeerUnverifiedException(e.getMessage());
-            } catch (javax.security.cert.CertificateException e) {
-                throw new SSLPeerUnverifiedException(e.getMessage());
-            }
-        }
-
-        return certs;
-    }
-
-    /**
-     * Return the cert chain presented by the peer.
-     * Note: This method can be used only when using certificate-based
-     * cipher suites; using it with non-certificate-based cipher suites,
-     * such as Kerberos, will throw an SSLPeerUnverifiedException.
-     *
-     * @return array of peer X.509 certs, with the peer's own cert
-     *  first in the chain, and with the "root" CA last.
-     */
-    public X509Certificate[] getCertificateChain()
-            throws SSLPeerUnverifiedException {
-        /*
-         * clone to preserve integrity of session ... caller can't
-         * change record of peer identity even by accident, much
-         * less do it intentionally.
-         */
-        if ((cipherSuite.keyExchange == K_KRB5) ||
-            (cipherSuite.keyExchange == K_KRB5_EXPORT)) {
-            throw new SSLPeerUnverifiedException("no certificates expected"
-                        + " for Kerberos cipher suites");
-        }
-        if (peerCerts != null) {
-            return peerCerts.clone();
-        } else {
-            throw new SSLPeerUnverifiedException("peer not authenticated");
-        }
-    }
-
-    /**
-     * Returns the identity of the peer which was established as part of
-     * defining the session.
-     *
-     * @return the peer's principal. Returns an X500Principal of the
-     * end-entity certificate for X509-based cipher suites, and
-     * Principal for Kerberos cipher suites.
-     *
-     * @throws SSLPeerUnverifiedException if the peer's identity has not
-     *          been verified
-     */
-    public Principal getPeerPrincipal()
-                throws SSLPeerUnverifiedException
-    {
-        if ((cipherSuite.keyExchange == K_KRB5) ||
-            (cipherSuite.keyExchange == K_KRB5_EXPORT)) {
-            if (peerPrincipal == null) {
-                throw new SSLPeerUnverifiedException("peer not authenticated");
-            } else {
-                // Eliminate dependency on KerberosPrincipal
-                return peerPrincipal;
-            }
-        }
-        if (peerCerts == null) {
-            throw new SSLPeerUnverifiedException("peer not authenticated");
-        }
-        return peerCerts[0].getSubjectX500Principal();
-    }
-
-    /**
-     * Returns the principal that was sent to the peer during handshaking.
-     *
-     * @return the principal sent to the peer. Returns an X500Principal
-     * of the end-entity certificate for X509-based cipher suites, and
-     * Principal for Kerberos cipher suites. If no principal was
-     * sent, then null is returned.
-     */
-    public Principal getLocalPrincipal() {
-
-        if ((cipherSuite.keyExchange == K_KRB5) ||
-            (cipherSuite.keyExchange == K_KRB5_EXPORT)) {
-                // Eliminate dependency on KerberosPrincipal
-                return (localPrincipal == null ? null : localPrincipal);
-        }
-        return (localCerts == null ? null :
-                localCerts[0].getSubjectX500Principal());
-    }
-
-    /**
-     * Returns the time this session was created.
-     */
-    public long getCreationTime() {
-        return creationTime;
-    }
-
-    /**
-     * Returns the last time this session was used to initialize
-     * a connection.
-     */
-    public long getLastAccessedTime() {
-        return (lastUsedTime != 0) ? lastUsedTime : creationTime;
-    }
-
-    void setLastAccessedTime(long time) {
-        lastUsedTime = time;
-    }
-
-
-    /**
-     * Returns the network address of the session's peer.  This
-     * implementation does not insist that connections between
-     * different ports on the same host must necessarily belong
-     * to different sessions, though that is of course allowed.
-     */
-    public InetAddress getPeerAddress() {
-        try {
-            return InetAddress.getByName(host);
-        } catch (java.net.UnknownHostException e) {
-            return null;
-        }
-    }
-
-    public String getPeerHost() {
-        return host;
-    }
-
-    /**
-     * Need to provide the port info for caching sessions based on
-     * host and port. Accessed by SSLSessionContextImpl
-     */
-    public int getPeerPort() {
-        return port;
-    }
-
-    void setContext(SSLSessionContextImpl ctx) {
-        if (context == null) {
-            context = ctx;
-        }
-    }
-
-    /**
-     * Invalidate a session.  Active connections may still exist, but
-     * no connections will be able to rejoin this session.
-     */
-    synchronized public void invalidate() {
-        //
-        // Can't invalidate the NULL session -- this would be
-        // attempted when we get a handshaking error on a brand
-        // new connection, with no "real" session yet.
-        //
-        if (this == nullSession) {
-            return;
-        }
-        invalidated = true;
-        if (debug != null && Debug.isOn("session")) {
-            System.out.println("%% Invalidated:  " + this);
-        }
-        if (context != null) {
-            context.remove(sessionId);
-            context = null;
-        }
-    }
-
-    /*
-     * Table of application-specific session data indexed by an application
-     * key and the calling security context. This is important since
-     * sessions can be shared across different protection domains.
-     */
-    private Hashtable<SecureKey, Object> table = new Hashtable<>();
-
-    /**
-     * Assigns a session value.  Session change events are given if
-     * appropriate, to any original value as well as the new value.
-     */
-    public void putValue(String key, Object value) {
-        if ((key == null) || (value == null)) {
-            throw new IllegalArgumentException("arguments can not be null");
-        }
-
-        SecureKey secureKey = new SecureKey(key);
-        Object oldValue = table.put(secureKey, value);
-
-        if (oldValue instanceof SSLSessionBindingListener) {
-            SSLSessionBindingEvent e;
-
-            e = new SSLSessionBindingEvent(this, key);
-            ((SSLSessionBindingListener)oldValue).valueUnbound(e);
-        }
-        if (value instanceof SSLSessionBindingListener) {
-            SSLSessionBindingEvent e;
-
-            e = new SSLSessionBindingEvent(this, key);
-            ((SSLSessionBindingListener)value).valueBound(e);
-        }
-    }
-
-
-    /**
-     * Returns the specified session value.
-     */
-    public Object getValue(String key) {
-        if (key == null) {
-            throw new IllegalArgumentException("argument can not be null");
-        }
-
-        SecureKey secureKey = new SecureKey(key);
-        return table.get(secureKey);
-    }
-
-
-    /**
-     * Removes the specified session value, delivering a session changed
-     * event as appropriate.
-     */
-    public void removeValue(String key) {
-        if (key == null) {
-            throw new IllegalArgumentException("argument can not be null");
-        }
-
-        SecureKey secureKey = new SecureKey(key);
-        Object value = table.remove(secureKey);
-
-        if (value instanceof SSLSessionBindingListener) {
-            SSLSessionBindingEvent e;
-
-            e = new SSLSessionBindingEvent(this, key);
-            ((SSLSessionBindingListener)value).valueUnbound(e);
-        }
-    }
-
-
-    /**
-     * Lists the names of the session values.
-     */
-    public String[] getValueNames() {
-        Enumeration<SecureKey> e;
-        Vector<Object> v = new Vector<>();
-        SecureKey key;
-        Object securityCtx = SecureKey.getCurrentSecurityContext();
-
-        for (e = table.keys(); e.hasMoreElements(); ) {
-            key = e.nextElement();
-
-            if (securityCtx.equals(key.getSecurityContext())) {
-                v.addElement(key.getAppKey());
-            }
-        }
-        String[] names = new String[v.size()];
-        v.copyInto(names);
-
-        return names;
-    }
-
-    /**
-     * Use large packet sizes now or follow RFC 2246 packet sizes (2^14)
-     * until changed.
-     *
-     * In the TLS specification (section 6.2.1, RFC2246), it is not
-     * recommended that the plaintext has more than 2^14 bytes.
-     * However, some TLS implementations violate the specification.
-     * This is a workaround for interoperability with these stacks.
-     *
-     * Application could accept large fragments up to 2^15 bytes by
-     * setting the system property jsse.SSLEngine.acceptLargeFragments
-     * to "true".
-     */
-    private boolean acceptLargeFragments =
-        Debug.getBooleanProperty("jsse.SSLEngine.acceptLargeFragments", false);
-
-    /**
-     * Expand the buffer size of both SSL/TLS network packet and
-     * application data.
-     */
-    protected synchronized void expandBufferSizes() {
-        acceptLargeFragments = true;
-    }
-
-    /**
-     * Gets the current size of the largest SSL/TLS packet that is expected
-     * when using this session.
-     */
-    public synchronized int getPacketBufferSize() {
-        return acceptLargeFragments ?
-                Record.maxLargeRecordSize : Record.maxRecordSize;
-    }
-
-    /**
-     * Gets the current size of the largest application data that is
-     * expected when using this session.
-     */
-    public synchronized int getApplicationBufferSize() {
-        return getPacketBufferSize() - Record.headerSize;
-    }
-
-    /**
-     * Gets an array of supported signature algorithms that the local side is
-     * willing to verify.
-     */
-    public String[] getLocalSupportedSignatureAlgorithms() {
-        if (localSupportedSignAlgs != null) {
-            return localSupportedSignAlgs.clone();
-        }
-
-        return new String[0];
-    }
-
-    /**
-     * Gets an array of supported signature algorithms that the peer is
-     * able to verify.
-     */
-    public String[] getPeerSupportedSignatureAlgorithms() {
-        if (peerSupportedSignAlgs != null) {
-            return peerSupportedSignAlgs.clone();
-        }
-
-        return new String[0];
-    }
-
-    /** Returns a string representation of this SSL session */
-    public String toString() {
-        return "[Session-" + sessionCount
-            + ", " + getCipherSuite()
-            + "]";
-    }
-
-    /**
-     * When SSL sessions are finalized, all values bound to
-     * them are removed.
-     */
-    public void finalize() {
-        String[] names = getValueNames();
-        for (int i = 0; i < names.length; i++) {
-            removeValue(names[i]);
-        }
-    }
-}
-
-
-/**
- * This "struct" class serves as a Hash Key that combines an
- * application-specific key and a security context.
- */
-class SecureKey {
-    private static Object       nullObject = new Object();
-    private Object        appKey;
-    private Object      securityCtx;
-
-    static Object getCurrentSecurityContext() {
-        SecurityManager sm = System.getSecurityManager();
-        Object context = null;
-
-        if (sm != null)
-            context = sm.getSecurityContext();
-        if (context == null)
-            context = nullObject;
-        return context;
-    }
-
-    SecureKey(Object key) {
-        this.appKey = key;
-        this.securityCtx = getCurrentSecurityContext();
-    }
-
-    Object getAppKey() {
-        return appKey;
-    }
-
-    Object getSecurityContext() {
-        return securityCtx;
-    }
-
-    public int hashCode() {
-        return appKey.hashCode() ^ securityCtx.hashCode();
-    }
-
-    public boolean equals(Object o) {
-        return o instanceof SecureKey && ((SecureKey)o).appKey.equals(appKey)
-                        && ((SecureKey)o).securityCtx.equals(securityCtx);
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/SSLSocketFactoryImpl.java b/ojluni/src/main/java/sun/security/ssl/SSLSocketFactoryImpl.java
deleted file mode 100755
index 135b462..0000000
--- a/ojluni/src/main/java/sun/security/ssl/SSLSocketFactoryImpl.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.net.*;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.SSLSocket;
-
-
-/**
- * Implementation of an SSL socket factory.  This provides the public
- * hooks to create SSL sockets, using a "high level" programming
- * interface which encapsulates system security policy defaults rather than
- * offering application flexibility.  In particular, it uses a configurable
- * authentication context (and the keys held there) rather than offering
- * any flexibility about which keys to use; that context defaults to the
- * process-default context, but may be explicitly specified.
- *
- * @author David Brownell
- */
-final public class SSLSocketFactoryImpl extends SSLSocketFactory {
-
-    private static SSLContextImpl defaultContext;
-    private SSLContextImpl context;
-
-    /**
-     * Constructor used to instantiate the default factory. This method is
-     * only called if the old "ssl.SocketFactory.provider" property in the
-     * java.security file is set.
-     */
-    public SSLSocketFactoryImpl() throws Exception {
-        this.context = SSLContextImpl.DefaultSSLContext.getDefaultImpl();
-    }
-
-    /**
-     * Constructs an SSL socket factory.
-     */
-    SSLSocketFactoryImpl(SSLContextImpl context) {
-        this.context = context;
-    }
-
-    /**
-     * Creates an unconnected socket.
-     *
-     * @return the unconnected socket
-     * @see java.net.Socket#connect(java.net.SocketAddress, int)
-     */
-    public Socket createSocket() {
-        return new SSLSocketImpl(context);
-    }
-
-    /**
-     * Constructs an SSL connection to a named host at a specified port.
-     * This acts as the SSL client, and may authenticate itself or rejoin
-     * existing SSL sessions allowed by the authentication context which
-     * has been configured.
-     *
-     * @param host name of the host with which to connect
-     * @param port number of the server's port
-     */
-    public Socket createSocket(String host, int port)
-    throws IOException, UnknownHostException
-    {
-        return new SSLSocketImpl(context, host, port);
-    }
-
-    /**
-     * Returns a socket layered over an existing socket to a
-     * ServerSocket on the named host, at the given port.  This
-     * constructor can be used when tunneling SSL through a proxy. The
-     * host and port refer to the logical destination server.  This
-     * socket is configured using the socket options established for
-     * this factory.
-     *
-     * @param s the existing socket
-     * @param host the server host
-     * @param port the server port
-     * @param autoClose close the underlying socket when this socket is closed
-     *
-     * @exception IOException if the connection can't be established
-     * @exception UnknownHostException if the host is not known
-     */
-    public Socket createSocket(Socket s, String host, int port,
-            boolean autoClose) throws IOException {
-        return new SSLSocketImpl(context, s, host, port, autoClose);
-    }
-
-
-    /**
-     * Constructs an SSL connection to a server at a specified address
-     * and TCP port.  This acts as the SSL client, and may authenticate
-     * itself or rejoin existing SSL sessions allowed by the authentication
-     * context which has been configured.
-     *
-     * @param address the server's host
-     * @param port its port
-     */
-    public Socket createSocket(InetAddress address, int port)
-    throws IOException
-    {
-        return new SSLSocketImpl(context, address, port);
-    }
-
-
-    /**
-     * Constructs an SSL connection to a named host at a specified port.
-     * This acts as the SSL client, and may authenticate itself or rejoin
-     * existing SSL sessions allowed by the authentication context which
-     * has been configured. The socket will also bind() to the local
-     * address and port supplied.
-     */
-    public Socket createSocket(String host, int port,
-        InetAddress clientAddress, int clientPort)
-    throws IOException
-    {
-        return new SSLSocketImpl(context, host, port,
-                clientAddress, clientPort);
-    }
-
-    /**
-     * Constructs an SSL connection to a server at a specified address
-     * and TCP port.  This acts as the SSL client, and may authenticate
-     * itself or rejoin existing SSL sessions allowed by the authentication
-     * context which has been configured. The socket will also bind() to
-     * the local address and port supplied.
-     */
-    public Socket createSocket(InetAddress address, int port,
-        InetAddress clientAddress, int clientPort)
-    throws IOException
-    {
-        return new SSLSocketImpl(context, address, port,
-                clientAddress, clientPort);
-    }
-
-
-    /**
-     * Returns the subset of the supported cipher suites which are
-     * enabled by default.  These cipher suites all provide a minimum
-     * quality of service whereby the server authenticates itself
-     * (preventing person-in-the-middle attacks) and where traffic
-     * is encrypted to provide confidentiality.
-     */
-    public String[] getDefaultCipherSuites() {
-        return context.getDefaultCipherSuiteList(false).toStringArray();
-    }
-
-    /**
-     * Returns the names of the cipher suites which could be enabled for use
-     * on an SSL connection.  Normally, only a subset of these will actually
-     * be enabled by default, since this list may include cipher suites which
-     * do not support the mutual authentication of servers and clients, or
-     * which do not protect data confidentiality.  Servers may also need
-     * certain kinds of certificates to use certain cipher suites.
-     */
-    public String[] getSupportedCipherSuites() {
-        return context.getSupportedCipherSuiteList().toStringArray();
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/SSLSocketImpl.java b/ojluni/src/main/java/sun/security/ssl/SSLSocketImpl.java
deleted file mode 100755
index 37158fb..0000000
--- a/ojluni/src/main/java/sun/security/ssl/SSLSocketImpl.java
+++ /dev/null
@@ -1,2545 +0,0 @@
-/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.net.*;
-import java.security.GeneralSecurityException;
-import java.security.AccessController;
-import java.security.AccessControlContext;
-import java.security.PrivilegedAction;
-import java.security.AlgorithmConstraints;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.ReentrantLock;
-
-import javax.crypto.BadPaddingException;
-
-import javax.net.ssl.*;
-
-import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager;
-
-/**
- * Implementation of an SSL socket.  This is a normal connection type
- * socket, implementing SSL over some lower level socket, such as TCP.
- * Because it is layered over some lower level socket, it MUST override
- * all default socket methods.
- *
- * <P> This API offers a non-traditional option for establishing SSL
- * connections.  You may first establish the connection directly, then pass
- * that connection to the SSL socket constructor with a flag saying which
- * role should be taken in the handshake protocol.  (The two ends of the
- * connection must not choose the same role!)  This allows setup of SSL
- * proxying or tunneling, and also allows the kind of "role reversal"
- * that is required for most FTP data transfers.
- *
- * @see javax.net.ssl.SSLSocket
- * @see SSLServerSocket
- *
- * @author David Brownell
- */
-final public class SSLSocketImpl extends BaseSSLSocketImpl {
-
-    /*
-     * ERROR HANDLING GUIDELINES
-     * (which exceptions to throw and catch and which not to throw and catch)
-     *
-     * . if there is an IOException (SocketException) when accessing the
-     *   underlying Socket, pass it through
-     *
-     * . do not throw IOExceptions, throw SSLExceptions (or a subclass)
-     *
-     * . for internal errors (things that indicate a bug in JSSE or a
-     *   grossly misconfigured J2RE), throw either an SSLException or
-     *   a RuntimeException at your convenience.
-     *
-     * . handshaking code (Handshaker or HandshakeMessage) should generally
-     *   pass through exceptions, but can handle them if they know what to
-     *   do.
-     *
-     * . exception chaining should be used for all new code. If you happen
-     *   to touch old code that does not use chaining, you should change it.
-     *
-     * . there is a top level exception handler that sits at all entry
-     *   points from application code to SSLSocket read/write code. It
-     *   makes sure that all errors are handled (see handleException()).
-     *
-     * . JSSE internal code should generally not call close(), call
-     *   closeInternal().
-     */
-
-    /*
-     * There's a state machine associated with each connection, which
-     * among other roles serves to negotiate session changes.
-     *
-     * - START with constructor, until the TCP connection's around.
-     * - HANDSHAKE picks session parameters before allowing traffic.
-     *          There are many substates due to sequencing requirements
-     *          for handshake messages.
-     * - DATA may be transmitted.
-     * - RENEGOTIATE state allows concurrent data and handshaking
-     *          traffic ("same" substates as HANDSHAKE), and terminates
-     *          in selection of new session (and connection) parameters
-     * - ERROR state immediately precedes abortive disconnect.
-     * - SENT_CLOSE sent a close_notify to the peer. For layered,
-     *          non-autoclose socket, must now read close_notify
-     *          from peer before closing the connection. For nonlayered or
-     *          non-autoclose socket, close connection and go onto
-     *          cs_CLOSED state.
-     * - CLOSED after sending close_notify alert, & socket is closed.
-     *          SSL connection objects are not reused.
-     * - APP_CLOSED once the application calls close(). Then it behaves like
-     *          a closed socket, e.g.. getInputStream() throws an Exception.
-     *
-     * State affects what SSL record types may legally be sent:
-     *
-     * - Handshake ... only in HANDSHAKE and RENEGOTIATE states
-     * - App Data ... only in DATA and RENEGOTIATE states
-     * - Alert ... in HANDSHAKE, DATA, RENEGOTIATE
-     *
-     * Re what may be received:  same as what may be sent, except that
-     * HandshakeRequest handshaking messages can come from servers even
-     * in the application data state, to request entry to RENEGOTIATE.
-     *
-     * The state machine within HANDSHAKE and RENEGOTIATE states controls
-     * the pending session, not the connection state, until the change
-     * cipher spec and "Finished" handshake messages are processed and
-     * make the "new" session become the current one.
-     *
-     * NOTE: details of the SMs always need to be nailed down better.
-     * The text above illustrates the core ideas.
-     *
-     *                +---->-------+------>--------->-------+
-     *                |            |                        |
-     *     <-----<    ^            ^  <-----<               v
-     *START>----->HANDSHAKE>----->DATA>----->RENEGOTIATE  SENT_CLOSE
-     *                v            v               v        |   |
-     *                |            |               |        |   v
-     *                +------------+---------------+        v ERROR
-     *                |                                     |   |
-     *                v                                     |   |
-     *               ERROR>------>----->CLOSED<--------<----+-- +
-     *                                     |
-     *                                     v
-     *                                 APP_CLOSED
-     *
-     * ALSO, note that the the purpose of handshaking (renegotiation is
-     * included) is to assign a different, and perhaps new, session to
-     * the connection.  The SSLv3 spec is a bit confusing on that new
-     * protocol feature.
-     */
-    private static final int    cs_START = 0;
-    private static final int    cs_HANDSHAKE = 1;
-    private static final int    cs_DATA = 2;
-    private static final int    cs_RENEGOTIATE = 3;
-    private static final int    cs_ERROR = 4;
-    private static final int   cs_SENT_CLOSE = 5;
-    private static final int    cs_CLOSED = 6;
-    private static final int    cs_APP_CLOSED = 7;
-
-
-    /*
-     * Client authentication be off, requested, or required.
-     *
-     * Migrated to SSLEngineImpl:
-     *    clauth_none/cl_auth_requested/clauth_required
-     */
-
-    /*
-     * Drives the protocol state machine.
-     */
-    private int                 connectionState;
-
-    /*
-     * Flag indicating if the next record we receive MUST be a Finished
-     * message. Temporarily set during the handshake to ensure that
-     * a change cipher spec message is followed by a finished message.
-     */
-    private boolean             expectingFinished;
-
-    /*
-     * For improved diagnostics, we detail connection closure
-     * If the socket is closed (connectionState >= cs_ERROR),
-     * closeReason != null indicates if the socket was closed
-     * because of an error or because or normal shutdown.
-     */
-    private SSLException        closeReason;
-
-    /*
-     * Per-connection private state that doesn't change when the
-     * session is changed.
-     */
-    private byte                doClientAuth;
-    private boolean             roleIsServer;
-    private boolean             enableSessionCreation = true;
-    private String              host;
-    private boolean             autoClose = true;
-    private AccessControlContext acc;
-
-    /*
-     * We cannot use the hostname resolved from name services.  For
-     * virtual hosting, multiple hostnames may be bound to the same IP
-     * address, so the hostname resolved from name services is not
-     * reliable.
-     */
-    private String              rawHostname;
-
-    // The cipher suites enabled for use on this connection.
-    private CipherSuiteList     enabledCipherSuites;
-
-    // The endpoint identification protocol
-    private String              identificationProtocol = null;
-
-    // The cryptographic algorithm constraints
-    private AlgorithmConstraints    algorithmConstraints = null;
-
-    /*
-     * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
-     * IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES.
-     * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
-     *
-     * There are several locks here.
-     *
-     * The primary lock is the per-instance lock used by
-     * synchronized(this) and the synchronized methods.  It controls all
-     * access to things such as the connection state and variables which
-     * affect handshaking.  If we are inside a synchronized method, we
-     * can access the state directly, otherwise, we must use the
-     * synchronized equivalents.
-     *
-     * The handshakeLock is used to ensure that only one thread performs
-     * the *complete initial* handshake.  If someone is handshaking, any
-     * stray application or startHandshake() requests who find the
-     * connection state is cs_HANDSHAKE will stall on handshakeLock
-     * until handshaking is done.  Once the handshake is done, we either
-     * succeeded or failed, but we can never go back to the cs_HANDSHAKE
-     * or cs_START state again.
-     *
-     * Note that the read/write() calls here in SSLSocketImpl are not
-     * obviously synchronized.  In fact, it's very nonintuitive, and
-     * requires careful examination of code paths.  Grab some coffee,
-     * and be careful with any code changes.
-     *
-     * There can be only three threads active at a time in the I/O
-     * subsection of this class.
-     *    1.  startHandshake
-     *    2.  AppInputStream
-     *    3.  AppOutputStream
-     * One thread could call startHandshake().
-     * AppInputStream/AppOutputStream read() and write() calls are each
-     * synchronized on 'this' in their respective classes, so only one
-     * app. thread will be doing a SSLSocketImpl.read() or .write()'s at
-     * a time.
-     *
-     * If handshaking is required (state cs_HANDSHAKE), and
-     * getConnectionState() for some/all threads returns cs_HANDSHAKE,
-     * only one can grab the handshakeLock, and the rest will stall
-     * either on getConnectionState(), or on the handshakeLock if they
-     * happen to successfully race through the getConnectionState().
-     *
-     * If a writer is doing the initial handshaking, it must create a
-     * temporary reader to read the responses from the other side.  As a
-     * side-effect, the writer's reader will have priority over any
-     * other reader.  However, the writer's reader is not allowed to
-     * consume any application data.  When handshakeLock is finally
-     * released, we either have a cs_DATA connection, or a
-     * cs_CLOSED/cs_ERROR socket.
-     *
-     * The writeLock is held while writing on a socket connection and
-     * also to protect the MAC and cipher for their direction.  The
-     * writeLock is package private for Handshaker which holds it while
-     * writing the ChangeCipherSpec message.
-     *
-     * To avoid the problem of a thread trying to change operational
-     * modes on a socket while handshaking is going on, we synchronize
-     * on 'this'.  If handshaking has not started yet, we tell the
-     * handshaker to change its mode.  If handshaking has started,
-     * we simply store that request until the next pending session
-     * is created, at which time the new handshaker's state is set.
-     *
-     * The readLock is held during readRecord(), which is responsible
-     * for reading an InputRecord, decrypting it, and processing it.
-     * The readLock ensures that these three steps are done atomically
-     * and that once started, no other thread can block on InputRecord.read.
-     * This is necessary so that processing of close_notify alerts
-     * from the peer are handled properly.
-     */
-    final private Object        handshakeLock = new Object();
-    final ReentrantLock         writeLock = new ReentrantLock();
-    final private Object        readLock = new Object();
-
-    private InputRecord         inrec;
-
-    /*
-     * Crypto state that's reinitialized when the session changes.
-     */
-    private MAC                 readMAC, writeMAC;
-    private CipherBox           readCipher, writeCipher;
-    // NOTE: compression state would be saved here
-
-    /*
-     * security parameters for secure renegotiation.
-     */
-    private boolean             secureRenegotiation;
-    private byte[]              clientVerifyData;
-    private byte[]              serverVerifyData;
-
-    /*
-     * The authentication context holds all information used to establish
-     * who this end of the connection is (certificate chains, private keys,
-     * etc) and who is trusted (e.g. as CAs or websites).
-     */
-    private SSLContextImpl      sslContext;
-
-
-    /*
-     * This connection is one of (potentially) many associated with
-     * any given session.  The output of the handshake protocol is a
-     * new session ... although all the protocol description talks
-     * about changing the cipher spec (and it does change), in fact
-     * that's incidental since it's done by changing everything that
-     * is associated with a session at the same time.  (TLS/IETF may
-     * change that to add client authentication w/o new key exchg.)
-     */
-    private Handshaker                  handshaker;
-    private SSLSessionImpl              sess;
-    private volatile SSLSessionImpl     handshakeSession;
-
-
-    /*
-     * If anyone wants to get notified about handshake completions,
-     * they'll show up on this list.
-     */
-    private HashMap<HandshakeCompletedListener, AccessControlContext>
-                                                        handshakeListeners;
-
-    /*
-     * Reuse the same internal input/output streams.
-     */
-    private InputStream         sockInput;
-    private OutputStream        sockOutput;
-
-
-    /*
-     * These input and output streams block their data in SSL records,
-     * and usually arrange integrity and privacy protection for those
-     * records.  The guts of the SSL protocol are wrapped up in these
-     * streams, and in the handshaking that establishes the details of
-     * that integrity and privacy protection.
-     */
-    private AppInputStream      input;
-    private AppOutputStream     output;
-
-    /*
-     * The protocol versions enabled for use on this connection.
-     *
-     * Note: we support a pseudo protocol called SSLv2Hello which when
-     * set will result in an SSL v2 Hello being sent with SSL (version 3.0)
-     * or TLS (version 3.1, 3.2, etc.) version info.
-     */
-    private ProtocolList enabledProtocols;
-
-    /*
-     * The SSL version associated with this connection.
-     */
-    private ProtocolVersion     protocolVersion = ProtocolVersion.DEFAULT;
-
-    /* Class and subclass dynamic debugging support */
-    private static final Debug debug = Debug.getInstance("ssl");
-
-    /*
-     * Is it the first application record to write?
-     */
-    private boolean isFirstAppOutputRecord = true;
-
-    /*
-     * If AppOutputStream needs to delay writes of small packets, we
-     * will use this to store the data until we actually do the write.
-     */
-    private ByteArrayOutputStream heldRecordBuffer = null;
-
-    //
-    // CONSTRUCTORS AND INITIALIZATION CODE
-    //
-
-    /**
-     * Constructs an SSL connection to a named host at a specified port,
-     * using the authentication context provided.  This endpoint acts as
-     * the client, and may rejoin an existing SSL session if appropriate.
-     *
-     * @param context authentication context to use
-     * @param host name of the host with which to connect
-     * @param port number of the server's port
-     */
-    SSLSocketImpl(SSLContextImpl context, String host, int port)
-            throws IOException, UnknownHostException {
-        super();
-        this.host = host;
-        this.rawHostname = host;
-        init(context, false);
-        SocketAddress socketAddress =
-               host != null ? new InetSocketAddress(host, port) :
-               new InetSocketAddress(InetAddress.getByName(null), port);
-        connect(socketAddress, 0);
-    }
-
-
-    /**
-     * Constructs an SSL connection to a server at a specified address.
-     * and TCP port, using the authentication context provided.  This
-     * endpoint acts as the client, and may rejoin an existing SSL session
-     * if appropriate.
-     *
-     * @param context authentication context to use
-     * @param address the server's host
-     * @param port its port
-     */
-    SSLSocketImpl(SSLContextImpl context, InetAddress host, int port)
-            throws IOException {
-        super();
-        init(context, false);
-        SocketAddress socketAddress = new InetSocketAddress(host, port);
-        connect(socketAddress, 0);
-    }
-
-    /**
-     * Constructs an SSL connection to a named host at a specified port,
-     * using the authentication context provided.  This endpoint acts as
-     * the client, and may rejoin an existing SSL session if appropriate.
-     *
-     * @param context authentication context to use
-     * @param host name of the host with which to connect
-     * @param port number of the server's port
-     * @param localAddr the local address the socket is bound to
-     * @param localPort the local port the socket is bound to
-     */
-    SSLSocketImpl(SSLContextImpl context, String host, int port,
-            InetAddress localAddr, int localPort)
-            throws IOException, UnknownHostException {
-        super();
-        this.host = host;
-        this.rawHostname = host;
-        init(context, false);
-        bind(new InetSocketAddress(localAddr, localPort));
-        SocketAddress socketAddress =
-               host != null ? new InetSocketAddress(host, port) :
-               new InetSocketAddress(InetAddress.getByName(null), port);
-        connect(socketAddress, 0);
-    }
-
-
-    /**
-     * Constructs an SSL connection to a server at a specified address.
-     * and TCP port, using the authentication context provided.  This
-     * endpoint acts as the client, and may rejoin an existing SSL session
-     * if appropriate.
-     *
-     * @param context authentication context to use
-     * @param address the server's host
-     * @param port its port
-     * @param localAddr the local address the socket is bound to
-     * @param localPort the local port the socket is bound to
-     */
-    SSLSocketImpl(SSLContextImpl context, InetAddress host, int port,
-            InetAddress localAddr, int localPort)
-            throws IOException {
-        super();
-        init(context, false);
-        bind(new InetSocketAddress(localAddr, localPort));
-        SocketAddress socketAddress = new InetSocketAddress(host, port);
-        connect(socketAddress, 0);
-    }
-
-    /*
-     * Package-private constructor used ONLY by SSLServerSocket.  The
-     * java.net package accepts the TCP connection after this call is
-     * made.  This just initializes handshake state to use "server mode",
-     * giving control over the use of SSL client authentication.
-     */
-    SSLSocketImpl(SSLContextImpl context, boolean serverMode,
-            CipherSuiteList suites, byte clientAuth,
-            boolean sessionCreation, ProtocolList protocols,
-            String identificationProtocol,
-            AlgorithmConstraints algorithmConstraints) throws IOException {
-
-        super();
-        doClientAuth = clientAuth;
-        enableSessionCreation = sessionCreation;
-        this.identificationProtocol = identificationProtocol;
-        this.algorithmConstraints = algorithmConstraints;
-        init(context, serverMode);
-
-        /*
-         * Override what was picked out for us.
-         */
-        enabledCipherSuites = suites;
-        enabledProtocols = protocols;
-    }
-
-
-    /**
-     * Package-private constructor used to instantiate an unconnected
-     * socket. The java.net package will connect it, either when the
-     * connect() call is made by the application.  This instance is
-     * meant to set handshake state to use "client mode".
-     */
-    SSLSocketImpl(SSLContextImpl context) {
-        super();
-        init(context, false);
-    }
-
-
-    /**
-     * Layer SSL traffic over an existing connection, rather than creating
-     * a new connection.  The existing connection may be used only for SSL
-     * traffic (using this SSLSocket) until the SSLSocket.close() call
-     * returns. However, if a protocol error is detected, that existing
-     * connection is automatically closed.
-     *
-     * <P> This particular constructor always uses the socket in the
-     * role of an SSL client. It may be useful in cases which start
-     * using SSL after some initial data transfers, for example in some
-     * SSL tunneling applications or as part of some kinds of application
-     * protocols which negotiate use of a SSL based security.
-     *
-     * @param sock the existing connection
-     * @param context the authentication context to use
-     */
-    SSLSocketImpl(SSLContextImpl context, Socket sock, String host,
-            int port, boolean autoClose) throws IOException {
-        super(sock);
-        // We always layer over a connected socket
-        if (!sock.isConnected()) {
-            throw new SocketException("Underlying socket is not connected");
-        }
-        this.host = host;
-        this.rawHostname = host;
-        init(context, false);
-        this.autoClose = autoClose;
-        doneConnect();
-    }
-
-    /**
-     * Initializes the client socket.
-     */
-    private void init(SSLContextImpl context, boolean isServer) {
-        sslContext = context;
-        sess = SSLSessionImpl.nullSession;
-        handshakeSession = null;
-
-        /*
-         * role is as specified, state is START until after
-         * the low level connection's established.
-         */
-        roleIsServer = isServer;
-        connectionState = cs_START;
-
-        /*
-         * default read and write side cipher and MAC support
-         *
-         * Note:  compression support would go here too
-         */
-        readCipher = CipherBox.NULL;
-        readMAC = MAC.NULL;
-        writeCipher = CipherBox.NULL;
-        writeMAC = MAC.NULL;
-
-        // initial security parameters for secure renegotiation
-        secureRenegotiation = false;
-        clientVerifyData = new byte[0];
-        serverVerifyData = new byte[0];
-
-        enabledCipherSuites =
-                sslContext.getDefaultCipherSuiteList(roleIsServer);
-        enabledProtocols =
-                sslContext.getDefaultProtocolList(roleIsServer);
-
-        inrec = null;
-
-        // save the acc
-        acc = AccessController.getContext();
-
-        input = new AppInputStream(this);
-        output = new AppOutputStream(this);
-    }
-
-    /**
-     * Connects this socket to the server with a specified timeout
-     * value.
-     *
-     * This method is either called on an unconnected SSLSocketImpl by the
-     * application, or it is called in the constructor of a regular
-     * SSLSocketImpl. If we are layering on top on another socket, then
-     * this method should not be called, because we assume that the
-     * underlying socket is already connected by the time it is passed to
-     * us.
-     *
-     * @param   endpoint the <code>SocketAddress</code>
-     * @param   timeout  the timeout value to be used, 0 is no timeout
-     * @throws  IOException if an error occurs during the connection
-     * @throws  SocketTimeoutException if timeout expires before connecting
-     */
-    public void connect(SocketAddress endpoint, int timeout)
-            throws IOException {
-
-        if (self != this) {
-            throw new SocketException("Already connected");
-        }
-
-        if (!(endpoint instanceof InetSocketAddress)) {
-            throw new SocketException(
-                                  "Cannot handle non-Inet socket addresses.");
-        }
-
-        super.connect(endpoint, timeout);
-        doneConnect();
-    }
-
-    /**
-     * Initialize the handshaker and socket streams.
-     *
-     * Called by connect, the layered constructor, and SSLServerSocket.
-     */
-    void doneConnect() throws IOException {
-        /*
-         * Save the input and output streams.  May be done only after
-         * java.net actually connects using the socket "self", else
-         * we get some pretty bizarre failure modes.
-         */
-        if (self == this) {
-            sockInput = super.getInputStream();
-            sockOutput = super.getOutputStream();
-        } else {
-            sockInput = self.getInputStream();
-            sockOutput = self.getOutputStream();
-        }
-
-        /*
-         * Move to handshaking state, with pending session initialized
-         * to defaults and the appropriate kind of handshaker set up.
-         */
-        initHandshaker();
-    }
-
-    synchronized private int getConnectionState() {
-        return connectionState;
-    }
-
-    synchronized private void setConnectionState(int state) {
-        connectionState = state;
-    }
-
-    AccessControlContext getAcc() {
-        return acc;
-    }
-
-    //
-    // READING AND WRITING RECORDS
-    //
-
-    /*
-     * AppOutputStream calls may need to buffer multiple outbound
-     * application packets.
-     *
-     * All other writeRecord() calls will not buffer, so do not hold
-     * these records.
-     */
-    void writeRecord(OutputRecord r) throws IOException {
-        writeRecord(r, false);
-    }
-
-    /*
-     * Record Output. Application data can't be sent until the first
-     * handshake establishes a session.
-     *
-     * NOTE:  we let empty records be written as a hook to force some
-     * TCP-level activity, notably handshaking, to occur.
-     */
-    void writeRecord(OutputRecord r, boolean holdRecord) throws IOException {
-        /*
-         * The loop is in case of HANDSHAKE --> ERROR transitions, etc
-         */
-    loop:
-        while (r.contentType() == Record.ct_application_data) {
-            /*
-             * Not all states support passing application data.  We
-             * synchronize access to the connection state, so that
-             * synchronous handshakes can complete cleanly.
-             */
-            switch (getConnectionState()) {
-
-            /*
-             * We've deferred the initial handshaking till just now,
-             * when presumably a thread's decided it's OK to block for
-             * longish periods of time for I/O purposes (as well as
-             * configured the cipher suites it wants to use).
-             */
-            case cs_HANDSHAKE:
-                performInitialHandshake();
-                break;
-
-            case cs_DATA:
-            case cs_RENEGOTIATE:
-                break loop;
-
-            case cs_ERROR:
-                fatal(Alerts.alert_close_notify,
-                    "error while writing to socket");
-                break; // dummy
-
-            case cs_SENT_CLOSE:
-            case cs_CLOSED:
-            case cs_APP_CLOSED:
-                // we should never get here (check in AppOutputStream)
-                // this is just a fallback
-                if (closeReason != null) {
-                    throw closeReason;
-                } else {
-                    throw new SocketException("Socket closed");
-                }
-
-            /*
-             * Else something's goofy in this state machine's use.
-             */
-            default:
-                throw new SSLProtocolException("State error, send app data");
-            }
-        }
-
-        //
-        // Don't bother to really write empty records.  We went this
-        // far to drive the handshake machinery, for correctness; not
-        // writing empty records improves performance by cutting CPU
-        // time and network resource usage.  However, some protocol
-        // implementations are fragile and don't like to see empty
-        // records, so this also increases robustness.
-        //
-        if (!r.isEmpty()) {
-
-            // If the record is a close notify alert, we need to honor
-            // socket option SO_LINGER. Note that we will try to send
-            // the close notify even if the SO_LINGER set to zero.
-            if (r.isAlert(Alerts.alert_close_notify) && getSoLinger() >= 0) {
-
-                // keep and clear the current thread interruption status.
-                boolean interrupted = Thread.interrupted();
-                try {
-                    if (writeLock.tryLock(getSoLinger(), TimeUnit.SECONDS)) {
-                        try {
-                            writeRecordInternal(r, holdRecord);
-                        } finally {
-                            writeLock.unlock();
-                        }
-                    } else {
-                        SSLException ssle = new SSLException(
-                                "SO_LINGER timeout," +
-                                " close_notify message cannot be sent.");
-
-
-                        // For layered, non-autoclose sockets, we are not
-                        // able to bring them into a usable state, so we
-                        // treat it as fatal error.
-                        if (self != this && !autoClose) {
-                            // Note that the alert description is
-                            // specified as -1, so no message will be send
-                            // to peer anymore.
-                            fatal((byte)(-1), ssle);
-                        } else if ((debug != null) && Debug.isOn("ssl")) {
-                            System.out.println(threadName() +
-                                ", received Exception: " + ssle);
-                        }
-
-                        // RFC2246 requires that the session becomes
-                        // unresumable if any connection is terminated
-                        // without proper close_notify messages with
-                        // level equal to warning.
-                        //
-                        // RFC4346 no longer requires that a session not be
-                        // resumed if failure to properly close a connection.
-                        //
-                        // We choose to make the session unresumable if
-                        // failed to send the close_notify message.
-                        //
-                        sess.invalidate();
-                    }
-                } catch (InterruptedException ie) {
-                    // keep interrupted status
-                    interrupted = true;
-                }
-
-                // restore the interrupted status
-                if (interrupted) {
-                    Thread.currentThread().interrupt();
-                }
-            } else {
-                writeLock.lock();
-                try {
-                    writeRecordInternal(r, holdRecord);
-                } finally {
-                    writeLock.unlock();
-                }
-            }
-        }
-    }
-
-    private void writeRecordInternal(OutputRecord r,
-            boolean holdRecord) throws IOException {
-        // r.compress(c);
-        r.addMAC(writeMAC);
-        r.encrypt(writeCipher);
-
-        if (holdRecord) {
-            // If we were requested to delay the record due to possibility
-            // of Nagle's being active when finally got to writing, and
-            // it's actually not, we don't really need to delay it.
-            if (getTcpNoDelay()) {
-                holdRecord = false;
-            } else {
-                // We need to hold the record, so let's provide
-                // a per-socket place to do it.
-                if (heldRecordBuffer == null) {
-                    // Likely only need 37 bytes.
-                    heldRecordBuffer = new ByteArrayOutputStream(40);
-                }
-            }
-        }
-        r.write(sockOutput, holdRecord, heldRecordBuffer);
-
-        /*
-         * Check the sequence number state
-         *
-         * Note that in order to maintain the connection I/O
-         * properly, we check the sequence number after the last
-         * record writing process. As we request renegotiation
-         * or close the connection for wrapped sequence number
-         * when there is enough sequence number space left to
-         * handle a few more records, so the sequence number
-         * of the last record cannot be wrapped.
-         */
-        if (connectionState < cs_ERROR) {
-            checkSequenceNumber(writeMAC, r.contentType());
-        }
-
-        // turn off the flag of the first application record
-        if (isFirstAppOutputRecord &&
-                r.contentType() == Record.ct_application_data) {
-            isFirstAppOutputRecord = false;
-        }
-    }
-
-    /*
-     * Need to split the payload except the following cases:
-     *
-     * 1. protocol version is TLS 1.1 or later;
-     * 2. bulk cipher does not use CBC mode, including null bulk cipher suites.
-     * 3. the payload is the first application record of a freshly
-     *    negotiated TLS session.
-     * 4. the CBC protection is disabled;
-     *
-     * More details, please refer to AppOutputStream.write(byte[], int, int).
-     */
-    boolean needToSplitPayload() {
-        writeLock.lock();
-        try {
-            return (protocolVersion.v <= ProtocolVersion.TLS10.v) &&
-                    writeCipher.isCBCMode() && !isFirstAppOutputRecord &&
-                    Record.enableCBCProtection;
-        } finally {
-            writeLock.unlock();
-        }
-    }
-
-    /*
-     * Read an application data record.  Alerts and handshake
-     * messages are handled directly.
-     */
-    void readDataRecord(InputRecord r) throws IOException {
-        if (getConnectionState() == cs_HANDSHAKE) {
-            performInitialHandshake();
-        }
-        readRecord(r, true);
-    }
-
-
-    /*
-     * Clear the pipeline of records from the peer, optionally returning
-     * application data.   Caller is responsible for knowing that it's
-     * possible to do this kind of clearing, if they don't want app
-     * data -- e.g. since it's the initial SSL handshake.
-     *
-     * Don't synchronize (this) during a blocking read() since it
-     * protects data which is accessed on the write side as well.
-     */
-    private void readRecord(InputRecord r, boolean needAppData)
-            throws IOException {
-        int state;
-
-        // readLock protects reading and processing of an InputRecord.
-        // It keeps the reading from sockInput and processing of the record
-        // atomic so that no two threads can be blocked on the
-        // read from the same input stream at the same time.
-        // This is required for example when a reader thread is
-        // blocked on the read and another thread is trying to
-        // close the socket. For a non-autoclose, layered socket,
-        // the thread performing the close needs to read the close_notify.
-        //
-        // Use readLock instead of 'this' for locking because
-        // 'this' also protects data accessed during writing.
-      synchronized (readLock) {
-        /*
-         * Read and handle records ... return application data
-         * ONLY if it's needed.
-         */
-
-        while (((state = getConnectionState()) != cs_CLOSED) &&
-                (state != cs_ERROR) && (state != cs_APP_CLOSED)) {
-            /*
-             * Read a record ... maybe emitting an alert if we get a
-             * comprehensible but unsupported "hello" message during
-             * format checking (e.g. V2).
-             */
-            try {
-                r.setAppDataValid(false);
-                r.read(sockInput, sockOutput);
-            } catch (SSLProtocolException e) {
-                try {
-                    fatal(Alerts.alert_unexpected_message, e);
-                } catch (IOException x) {
-                    // discard this exception
-                }
-                throw e;
-            } catch (EOFException eof) {
-                boolean handshaking = (getConnectionState() <= cs_HANDSHAKE);
-                boolean rethrow = requireCloseNotify || handshaking;
-                if ((debug != null) && Debug.isOn("ssl")) {
-                    System.out.println(threadName() +
-                        ", received EOFException: "
-                        + (rethrow ? "error" : "ignored"));
-                }
-                if (rethrow) {
-                    SSLException e;
-                    if (handshaking) {
-                        e = new SSLHandshakeException
-                            ("Remote host closed connection during handshake");
-                    } else {
-                        e = new SSLProtocolException
-                            ("Remote host closed connection incorrectly");
-                    }
-                    e.initCause(eof);
-                    throw e;
-                } else {
-                    // treat as if we had received a close_notify
-                    closeInternal(false);
-                    continue;
-                }
-            }
-
-
-            /*
-             * The basic SSLv3 record protection involves (optional)
-             * encryption for privacy, and an integrity check ensuring
-             * data origin authentication.  We do them both here, and
-             * throw a fatal alert if the integrity check fails.
-             */
-            try {
-                r.decrypt(readMAC, readCipher);
-            } catch (BadPaddingException e) {
-                byte alertType = (r.contentType() == Record.ct_handshake)
-                                        ? Alerts.alert_handshake_failure
-                                        : Alerts.alert_bad_record_mac;
-                fatal(alertType, e.getMessage(), e);
-            }
-
-            // if (!r.decompress(c))
-            //     fatal(Alerts.alert_decompression_failure,
-            //         "decompression failure");
-
-            /*
-             * Process the record.
-             */
-            synchronized (this) {
-              switch (r.contentType()) {
-                case Record.ct_handshake:
-                    /*
-                     * Handshake messages always go to a pending session
-                     * handshaker ... if there isn't one, create one.  This
-                     * must work asynchronously, for renegotiation.
-                     *
-                     * NOTE that handshaking will either resume a session
-                     * which was in the cache (and which might have other
-                     * connections in it already), or else will start a new
-                     * session (new keys exchanged) with just this connection
-                     * in it.
-                     */
-                    initHandshaker();
-                    if (!handshaker.activated()) {
-                        // prior to handshaking, activate the handshake
-                        if (connectionState == cs_RENEGOTIATE) {
-                            // don't use SSLv2Hello when renegotiating
-                            handshaker.activate(protocolVersion);
-                        } else {
-                            handshaker.activate(null);
-                        }
-                    }
-
-                    /*
-                     * process the handshake record ... may contain just
-                     * a partial handshake message or multiple messages.
-                     *
-                     * The handshaker state machine will ensure that it's
-                     * a finished message.
-                     */
-                    handshaker.process_record(r, expectingFinished);
-                    expectingFinished = false;
-
-                    if (handshaker.invalidated) {
-                        handshaker = null;
-                        // if state is cs_RENEGOTIATE, revert it to cs_DATA
-                        if (connectionState == cs_RENEGOTIATE) {
-                            connectionState = cs_DATA;
-                        }
-                    } else if (handshaker.isDone()) {
-                        // reset the parameters for secure renegotiation.
-                        secureRenegotiation =
-                                        handshaker.isSecureRenegotiation();
-                        clientVerifyData = handshaker.getClientVerifyData();
-                        serverVerifyData = handshaker.getServerVerifyData();
-
-                        sess = handshaker.getSession();
-                        handshakeSession = null;
-                        handshaker = null;
-                        connectionState = cs_DATA;
-
-                        //
-                        // Tell folk about handshake completion, but do
-                        // it in a separate thread.
-                        //
-                        if (handshakeListeners != null) {
-                            HandshakeCompletedEvent event =
-                                new HandshakeCompletedEvent(this, sess);
-
-                            Thread t = new NotifyHandshakeThread(
-                                handshakeListeners.entrySet(), event);
-                            t.start();
-                        }
-                    }
-
-                    if (needAppData || connectionState != cs_DATA) {
-                        continue;
-                    }
-                    break;
-
-                case Record.ct_application_data:
-                    // Pass this right back up to the application.
-                    if (connectionState != cs_DATA
-                            && connectionState != cs_RENEGOTIATE
-                            && connectionState != cs_SENT_CLOSE) {
-                        throw new SSLProtocolException(
-                            "Data received in non-data state: " +
-                            connectionState);
-                    }
-                    if (expectingFinished) {
-                        throw new SSLProtocolException
-                                ("Expecting finished message, received data");
-                    }
-                    if (!needAppData) {
-                        throw new SSLException("Discarding app data");
-                    }
-
-                    r.setAppDataValid(true);
-                    break;
-
-                case Record.ct_alert:
-                    recvAlert(r);
-                    continue;
-
-                case Record.ct_change_cipher_spec:
-                    if ((connectionState != cs_HANDSHAKE
-                                && connectionState != cs_RENEGOTIATE)
-                            || r.available() != 1
-                            || r.read() != 1) {
-                        fatal(Alerts.alert_unexpected_message,
-                            "illegal change cipher spec msg, state = "
-                            + connectionState);
-                    }
-
-                    //
-                    // The first message after a change_cipher_spec
-                    // record MUST be a "Finished" handshake record,
-                    // else it's a protocol violation.  We force this
-                    // to be checked by a minor tweak to the state
-                    // machine.
-                    //
-                    changeReadCiphers();
-                    // next message MUST be a finished message
-                    expectingFinished = true;
-                    continue;
-
-                default:
-                    //
-                    // TLS requires that unrecognized records be ignored.
-                    //
-                    if (debug != null && Debug.isOn("ssl")) {
-                        System.out.println(threadName() +
-                            ", Received record type: "
-                            + r.contentType());
-                    }
-                    continue;
-              } // switch
-
-              /*
-               * Check the sequence number state
-               *
-               * Note that in order to maintain the connection I/O
-               * properly, we check the sequence number after the last
-               * record reading process. As we request renegotiation
-               * or close the connection for wrapped sequence number
-               * when there is enough sequence number space left to
-               * handle a few more records, so the sequence number
-               * of the last record cannot be wrapped.
-               */
-              if (connectionState < cs_ERROR) {
-                  checkSequenceNumber(readMAC, r.contentType());
-              }
-
-              return;
-            } // synchronized (this)
-        }
-
-        //
-        // couldn't read, due to some kind of error
-        //
-        r.close();
-        return;
-      }  // synchronized (readLock)
-    }
-
-    /**
-     * Check the sequence number state
-     *
-     * RFC 4346 states that, "Sequence numbers are of type uint64 and
-     * may not exceed 2^64-1.  Sequence numbers do not wrap. If a TLS
-     * implementation would need to wrap a sequence number, it must
-     * renegotiate instead."
-     */
-    private void checkSequenceNumber(MAC mac, byte type)
-            throws IOException {
-
-        /*
-         * Don't bother to check the sequence number for error or
-         * closed connections, or NULL MAC.
-         */
-        if (connectionState >= cs_ERROR || mac == MAC.NULL) {
-            return;
-        }
-
-        /*
-         * Conservatively, close the connection immediately when the
-         * sequence number is close to overflow
-         */
-        if (mac.seqNumOverflow()) {
-            /*
-             * TLS protocols do not define a error alert for sequence
-             * number overflow. We use handshake_failure error alert
-             * for handshaking and bad_record_mac for other records.
-             */
-            if (debug != null && Debug.isOn("ssl")) {
-                System.out.println(threadName() +
-                    ", sequence number extremely close to overflow " +
-                    "(2^64-1 packets). Closing connection.");
-
-            }
-
-            fatal(Alerts.alert_handshake_failure, "sequence number overflow");
-        }
-
-        /*
-         * Ask for renegotiation when need to renew sequence number.
-         *
-         * Don't bother to kickstart the renegotiation when the local is
-         * asking for it.
-         */
-        if ((type != Record.ct_handshake) && mac.seqNumIsHuge()) {
-            if (debug != null && Debug.isOn("ssl")) {
-                System.out.println(threadName() + ", request renegotiation " +
-                        "to avoid sequence number overflow");
-            }
-
-            startHandshake();
-        }
-    }
-
-    //
-    // HANDSHAKE RELATED CODE
-    //
-
-    /**
-     * Return the AppInputStream. For use by Handshaker only.
-     */
-    AppInputStream getAppInputStream() {
-        return input;
-    }
-
-    /**
-     * Return the AppOutputStream. For use by Handshaker only.
-     */
-    AppOutputStream getAppOutputStream() {
-        return output;
-    }
-
-    /**
-     * Initialize the handshaker object. This means:
-     *
-     *  . if a handshake is already in progress (state is cs_HANDSHAKE
-     *    or cs_RENEGOTIATE), do nothing and return
-     *
-     *  . if the socket is already closed, throw an Exception (internal error)
-     *
-     *  . otherwise (cs_START or cs_DATA), create the appropriate handshaker
-     *    object, and advance the connection state (to cs_HANDSHAKE or
-     *    cs_RENEGOTIATE, respectively).
-     *
-     * This method is called right after a new socket is created, when
-     * starting renegotiation, or when changing client/ server mode of the
-     * socket.
-     */
-    private void initHandshaker() {
-        switch (connectionState) {
-
-        //
-        // Starting a new handshake.
-        //
-        case cs_START:
-        case cs_DATA:
-            break;
-
-        //
-        // We're already in the middle of a handshake.
-        //
-        case cs_HANDSHAKE:
-        case cs_RENEGOTIATE:
-            return;
-
-        //
-        // Anyone allowed to call this routine is required to
-        // do so ONLY if the connection state is reasonable...
-        //
-        default:
-            throw new IllegalStateException("Internal error");
-        }
-
-        // state is either cs_START or cs_DATA
-        if (connectionState == cs_START) {
-            connectionState = cs_HANDSHAKE;
-        } else { // cs_DATA
-            connectionState = cs_RENEGOTIATE;
-        }
-        if (roleIsServer) {
-            handshaker = new ServerHandshaker(this, sslContext,
-                    enabledProtocols, doClientAuth,
-                    protocolVersion, connectionState == cs_HANDSHAKE,
-                    secureRenegotiation, clientVerifyData, serverVerifyData);
-        } else {
-            handshaker = new ClientHandshaker(this, sslContext,
-                    enabledProtocols,
-                    protocolVersion, connectionState == cs_HANDSHAKE,
-                    secureRenegotiation, clientVerifyData, serverVerifyData);
-        }
-        handshaker.setEnabledCipherSuites(enabledCipherSuites);
-        handshaker.setEnableSessionCreation(enableSessionCreation);
-    }
-
-    /**
-     * Synchronously perform the initial handshake.
-     *
-     * If the handshake is already in progress, this method blocks until it
-     * is completed. If the initial handshake has already been completed,
-     * it returns immediately.
-     */
-    private void performInitialHandshake() throws IOException {
-        // use handshakeLock and the state check to make sure only
-        // one thread performs the handshake
-        synchronized (handshakeLock) {
-            if (getConnectionState() == cs_HANDSHAKE) {
-                kickstartHandshake();
-
-                /*
-                 * All initial handshaking goes through this
-                 * InputRecord until we have a valid SSL connection.
-                 * Once initial handshaking is finished, AppInputStream's
-                 * InputRecord can handle any future renegotiation.
-                 *
-                 * Keep this local so that it goes out of scope and is
-                 * eventually GC'd.
-                 */
-                if (inrec == null) {
-                    inrec = new InputRecord();
-
-                    /*
-                     * Grab the characteristics already assigned to
-                     * AppInputStream's InputRecord.  Enable checking for
-                     * SSLv2 hellos on this first handshake.
-                     */
-                    inrec.setHandshakeHash(input.r.getHandshakeHash());
-                    inrec.setHelloVersion(input.r.getHelloVersion());
-                    inrec.enableFormatChecks();
-                }
-
-                readRecord(inrec, false);
-                inrec = null;
-            }
-        }
-    }
-
-    /**
-     * Starts an SSL handshake on this connection.
-     */
-    public void startHandshake() throws IOException {
-        // start an ssl handshake that could be resumed from timeout exception
-        startHandshake(true);
-    }
-
-    /**
-     * Starts an ssl handshake on this connection.
-     *
-     * @param resumable indicates the handshake process is resumable from a
-     *          certain exception. If <code>resumable</code>, the socket will
-     *          be reserved for exceptions like timeout; otherwise, the socket
-     *          will be closed, no further communications could be done.
-     */
-    private void startHandshake(boolean resumable) throws IOException {
-        checkWrite();
-        try {
-            if (getConnectionState() == cs_HANDSHAKE) {
-                // do initial handshake
-                performInitialHandshake();
-            } else {
-                // start renegotiation
-                kickstartHandshake();
-            }
-        } catch (Exception e) {
-            // shutdown and rethrow (wrapped) exception as appropriate
-            handleException(e, resumable);
-        }
-    }
-
-    /**
-     * Kickstart the handshake if it is not already in progress.
-     * This means:
-     *
-     *  . if handshaking is already underway, do nothing and return
-     *
-     *  . if the socket is not connected or already closed, throw an
-     *    Exception.
-     *
-     *  . otherwise, call initHandshake() to initialize the handshaker
-     *    object and progress the state. Then, send the initial
-     *    handshaking message if appropriate (always on clients and
-     *    on servers when renegotiating).
-     */
-    private synchronized void kickstartHandshake() throws IOException {
-
-        switch (connectionState) {
-
-        case cs_HANDSHAKE:
-            // handshaker already setup, proceed
-            break;
-
-        case cs_DATA:
-            if (!secureRenegotiation && !Handshaker.allowUnsafeRenegotiation) {
-                throw new SSLHandshakeException(
-                        "Insecure renegotiation is not allowed");
-            }
-
-            if (!secureRenegotiation) {
-                if (debug != null && Debug.isOn("handshake")) {
-                    System.out.println(
-                        "Warning: Using insecure renegotiation");
-                }
-            }
-
-            // initialize the handshaker, move to cs_RENEGOTIATE
-            initHandshaker();
-            break;
-
-        case cs_RENEGOTIATE:
-            // handshaking already in progress, return
-            return;
-
-        /*
-         * The only way to get a socket in the state is when
-         * you have an unconnected socket.
-         */
-        case cs_START:
-            throw new SocketException(
-                "handshaking attempted on unconnected socket");
-
-        default:
-            throw new SocketException("connection is closed");
-        }
-
-        //
-        // Kickstart handshake state machine if we need to ...
-        //
-        // Note that handshaker.kickstart() writes the message
-        // to its HandshakeOutStream, which calls back into
-        // SSLSocketImpl.writeRecord() to send it.
-        //
-        if (!handshaker.activated()) {
-             // prior to handshaking, activate the handshake
-            if (connectionState == cs_RENEGOTIATE) {
-                // don't use SSLv2Hello when renegotiating
-                handshaker.activate(protocolVersion);
-            } else {
-                handshaker.activate(null);
-            }
-
-            if (handshaker instanceof ClientHandshaker) {
-                // send client hello
-                handshaker.kickstart();
-            } else {
-                if (connectionState == cs_HANDSHAKE) {
-                    // initial handshake, no kickstart message to send
-                } else {
-                    // we want to renegotiate, send hello request
-                    handshaker.kickstart();
-                    // hello request is not included in the handshake
-                    // hashes, reset them
-                    handshaker.handshakeHash.reset();
-                }
-            }
-        }
-    }
-
-    //
-    // CLOSURE RELATED CALLS
-    //
-
-    /**
-     * Return whether the socket has been explicitly closed by the application.
-     */
-    public boolean isClosed() {
-        return getConnectionState() == cs_APP_CLOSED;
-    }
-
-    /**
-     * Return whether we have reached end-of-file.
-     *
-     * If the socket is not connected, has been shutdown because of an error
-     * or has been closed, throw an Exception.
-     */
-    boolean checkEOF() throws IOException {
-        switch (getConnectionState()) {
-        case cs_START:
-            throw new SocketException("Socket is not connected");
-
-        case cs_HANDSHAKE:
-        case cs_DATA:
-        case cs_RENEGOTIATE:
-        case cs_SENT_CLOSE:
-            return false;
-
-        case cs_APP_CLOSED:
-            throw new SocketException("Socket is closed");
-
-        case cs_ERROR:
-        case cs_CLOSED:
-        default:
-            // either closed because of error, or normal EOF
-            if (closeReason == null) {
-                return true;
-            }
-            IOException e = new SSLException
-                        ("Connection has been shutdown: " + closeReason);
-            e.initCause(closeReason);
-            throw e;
-
-        }
-    }
-
-    /**
-     * Check if we can write data to this socket. If not, throw an IOException.
-     */
-    void checkWrite() throws IOException {
-        if (checkEOF() || (getConnectionState() == cs_SENT_CLOSE)) {
-            // we are at EOF, write must throw Exception
-            throw new SocketException("Connection closed by remote host");
-        }
-    }
-
-    protected void closeSocket() throws IOException {
-
-        if ((debug != null) && Debug.isOn("ssl")) {
-            System.out.println(threadName() + ", called closeSocket()");
-        }
-        if (self == this) {
-            super.close();
-        } else {
-            self.close();
-        }
-    }
-
-    private void closeSocket(boolean selfInitiated) throws IOException {
-        if ((debug != null) && Debug.isOn("ssl")) {
-            System.out.println(threadName() + ", called closeSocket(selfInitiated)");
-        }
-        if (self == this) {
-            super.close();
-        } else if (autoClose) {
-            self.close();
-        } else if (selfInitiated) {
-            // layered && non-autoclose
-            // read close_notify alert to clear input stream
-            waitForClose(false);
-        }
-    }
-
-    /*
-     * Closing the connection is tricky ... we can't officially close the
-     * connection until we know the other end is ready to go away too,
-     * and if ever the connection gets aborted we must forget session
-     * state (it becomes invalid).
-     */
-
-    /**
-     * Closes the SSL connection.  SSL includes an application level
-     * shutdown handshake; you should close SSL sockets explicitly
-     * rather than leaving it for finalization, so that your remote
-     * peer does not experience a protocol error.
-     */
-    public void close() throws IOException {
-        if ((debug != null) && Debug.isOn("ssl")) {
-            System.out.println(threadName() + ", called close()");
-        }
-        closeInternal(true);  // caller is initiating close
-        setConnectionState(cs_APP_CLOSED);
-    }
-
-    /**
-     * Don't synchronize the whole method because waitForClose()
-     * (which calls readRecord()) might be called.
-     *
-     * @param selfInitiated Indicates which party initiated the close.
-     * If selfInitiated, this side is initiating a close; for layered and
-     * non-autoclose socket, wait for close_notify response.
-     * If !selfInitiated, peer sent close_notify; we reciprocate but
-     * no need to wait for response.
-     */
-    private void closeInternal(boolean selfInitiated) throws IOException {
-        if ((debug != null) && Debug.isOn("ssl")) {
-            System.out.println(threadName() + ", called closeInternal("
-                + selfInitiated + ")");
-        }
-
-        int state = getConnectionState();
-        boolean closeSocketCalled = false;
-        Throwable cachedThrowable = null;
-        try {
-            switch (state) {
-            case cs_START:
-                // unconnected socket or handshaking has not been initialized
-                closeSocket(selfInitiated);
-                break;
-
-            /*
-             * If we're closing down due to error, we already sent (or else
-             * received) the fatal alert ... no niceties, blow the connection
-             * away as quickly as possible (even if we didn't allocate the
-             * socket ourselves; it's unusable, regardless).
-             */
-            case cs_ERROR:
-                closeSocket();
-                break;
-
-            /*
-             * Sometimes close() gets called more than once.
-             */
-            case cs_CLOSED:
-            case cs_APP_CLOSED:
-                 break;
-
-            /*
-             * Otherwise we indicate clean termination.
-             */
-            // case cs_HANDSHAKE:
-            // case cs_DATA:
-            // case cs_RENEGOTIATE:
-            // case cs_SENT_CLOSE:
-            default:
-                synchronized (this) {
-                    if (((state = getConnectionState()) == cs_CLOSED) ||
-                       (state == cs_ERROR) || (state == cs_APP_CLOSED)) {
-                        return;  // connection was closed while we waited
-                    }
-                    if (state != cs_SENT_CLOSE) {
-                        try {
-                            warning(Alerts.alert_close_notify);
-                            connectionState = cs_SENT_CLOSE;
-                        } catch (Throwable th) {
-                            // we need to ensure socket is closed out
-                            // if we encounter any errors.
-                            connectionState = cs_ERROR;
-                            // cache this for later use
-                            cachedThrowable = th;
-                            closeSocketCalled = true;
-                            closeSocket(selfInitiated);
-                        }
-                    }
-                }
-                // If state was cs_SENT_CLOSE before, we don't do the actual
-                // closing since it is already in progress.
-                if (state == cs_SENT_CLOSE) {
-                    if (debug != null && Debug.isOn("ssl")) {
-                        System.out.println(threadName() +
-                            ", close invoked again; state = " +
-                            getConnectionState());
-                    }
-                    if (selfInitiated == false) {
-                        // We were called because a close_notify message was
-                        // received. This may be due to another thread calling
-                        // read() or due to our call to waitForClose() below.
-                        // In either case, just return.
-                        return;
-                    }
-                    // Another thread explicitly called close(). We need to
-                    // wait for the closing to complete before returning.
-                    synchronized (this) {
-                        while (connectionState < cs_CLOSED) {
-                            try {
-                                this.wait();
-                            } catch (InterruptedException e) {
-                                // ignore
-                            }
-                        }
-                    }
-                    if ((debug != null) && Debug.isOn("ssl")) {
-                        System.out.println(threadName() +
-                            ", after primary close; state = " +
-                            getConnectionState());
-                    }
-                    return;
-                }
-
-                if (!closeSocketCalled)  {
-                    closeSocketCalled = true;
-                    closeSocket(selfInitiated);
-                }
-
-                break;
-            }
-        } finally {
-            synchronized (this) {
-                // Upon exit from this method, the state is always >= cs_CLOSED
-                connectionState = (connectionState == cs_APP_CLOSED)
-                                ? cs_APP_CLOSED : cs_CLOSED;
-                // notify any threads waiting for the closing to finish
-                this.notifyAll();
-            }
-            if (closeSocketCalled) {
-                // Dispose of ciphers since we've closed socket
-                disposeCiphers();
-            }
-            if (cachedThrowable != null) {
-               /*
-                * Rethrow the error to the calling method
-                * The Throwable caught can only be an Error or RuntimeException
-                */
-                if (cachedThrowable instanceof Error)
-                    throw (Error) cachedThrowable;
-                if (cachedThrowable instanceof RuntimeException)
-                    throw (RuntimeException) cachedThrowable;
-            }
-        }
-    }
-
-    /**
-     * Reads a close_notify or a fatal alert from the input stream.
-     * Keep reading records until we get a close_notify or until
-     * the connection is otherwise closed.  The close_notify or alert
-     * might be read by another reader,
-     * which will then process the close and set the connection state.
-     */
-    void waitForClose(boolean rethrow) throws IOException {
-        if (debug != null && Debug.isOn("ssl")) {
-            System.out.println(threadName() +
-                ", waiting for close_notify or alert: state "
-                + getConnectionState());
-        }
-
-        try {
-            int state;
-
-            while (((state = getConnectionState()) != cs_CLOSED) &&
-                   (state != cs_ERROR) && (state != cs_APP_CLOSED)) {
-                // create the InputRecord if it isn't intialized.
-                if (inrec == null) {
-                    inrec = new InputRecord();
-                }
-
-                // Ask for app data and then throw it away
-                try {
-                    readRecord(inrec, true);
-                } catch (SocketTimeoutException e) {
-                    // if time out, ignore the exception and continue
-                }
-            }
-            inrec = null;
-        } catch (IOException e) {
-            if (debug != null && Debug.isOn("ssl")) {
-                System.out.println(threadName() +
-                    ", Exception while waiting for close " +e);
-            }
-            if (rethrow) {
-                throw e; // pass exception up
-            }
-        }
-    }
-
-    /**
-     * Called by closeInternal() only. Be sure to consider the
-     * synchronization locks carefully before calling it elsewhere.
-     */
-    private void disposeCiphers() {
-        // See comment in changeReadCiphers()
-        synchronized (readLock) {
-            readCipher.dispose();
-        }
-        // See comment in changeReadCiphers()
-        writeLock.lock();
-        try {
-            writeCipher.dispose();
-        } finally {
-            writeLock.unlock();
-        }
-    }
-
-    //
-    // EXCEPTION AND ALERT HANDLING
-    //
-
-    /**
-     * Handle an exception. This method is called by top level exception
-     * handlers (in read(), write()) to make sure we always shutdown the
-     * connection correctly and do not pass runtime exception to the
-     * application.
-     */
-    void handleException(Exception e) throws IOException {
-        handleException(e, true);
-    }
-
-    /**
-     * Handle an exception. This method is called by top level exception
-     * handlers (in read(), write(), startHandshake()) to make sure we
-     * always shutdown the connection correctly and do not pass runtime
-     * exception to the application.
-     *
-     * This method never returns normally, it always throws an IOException.
-     *
-     * We first check if the socket has already been shutdown because of an
-     * error. If so, we just rethrow the exception. If the socket has not
-     * been shutdown, we sent a fatal alert and remember the exception.
-     *
-     * @param e the Exception
-     * @param resumable indicates the caller process is resumable from the
-     *          exception. If <code>resumable</code>, the socket will be
-     *          reserved for exceptions like timeout; otherwise, the socket
-     *          will be closed, no further communications could be done.
-     */
-    synchronized private void handleException(Exception e, boolean resumable)
-        throws IOException {
-        if ((debug != null) && Debug.isOn("ssl")) {
-            System.out.println(threadName()
-                        + ", handling exception: " + e.toString());
-        }
-
-        // don't close the Socket in case of timeouts or interrupts if
-        // the process is resumable.
-        if (e instanceof InterruptedIOException && resumable) {
-            throw (IOException)e;
-        }
-
-        // if we've already shutdown because of an error,
-        // there is nothing to do except rethrow the exception
-        if (closeReason != null) {
-            if (e instanceof IOException) { // includes SSLException
-                throw (IOException)e;
-            } else {
-                // this is odd, not an IOException.
-                // normally, this should not happen
-                // if closeReason has been already been set
-                throw Alerts.getSSLException(Alerts.alert_internal_error, e,
-                                      "Unexpected exception");
-            }
-        }
-
-        // need to perform error shutdown
-        boolean isSSLException = (e instanceof SSLException);
-        if ((isSSLException == false) && (e instanceof IOException)) {
-            // IOException from the socket
-            // this means the TCP connection is already dead
-            // we call fatal just to set the error status
-            try {
-                fatal(Alerts.alert_unexpected_message, e);
-            } catch (IOException ee) {
-                // ignore (IOException wrapped in SSLException)
-            }
-            // rethrow original IOException
-            throw (IOException)e;
-        }
-
-        // must be SSLException or RuntimeException
-        byte alertType;
-        if (isSSLException) {
-            if (e instanceof SSLHandshakeException) {
-                alertType = Alerts.alert_handshake_failure;
-            } else {
-                alertType = Alerts.alert_unexpected_message;
-            }
-        } else {
-            alertType = Alerts.alert_internal_error;
-        }
-        fatal(alertType, e);
-    }
-
-    /*
-     * Send a warning alert.
-     */
-    void warning(byte description) {
-        sendAlert(Alerts.alert_warning, description);
-    }
-
-    synchronized void fatal(byte description, String diagnostic)
-            throws IOException {
-        fatal(description, diagnostic, null);
-    }
-
-    synchronized void fatal(byte description, Throwable cause)
-            throws IOException {
-        fatal(description, null, cause);
-    }
-
-    /*
-     * Send a fatal alert, and throw an exception so that callers will
-     * need to stand on their heads to accidentally continue processing.
-     */
-    synchronized void fatal(byte description, String diagnostic,
-            Throwable cause) throws IOException {
-        if ((input != null) && (input.r != null)) {
-            input.r.close();
-        }
-        sess.invalidate();
-        if (handshakeSession != null) {
-            handshakeSession.invalidate();
-        }
-
-        int oldState = connectionState;
-        if (connectionState < cs_ERROR) {
-            connectionState = cs_ERROR;
-        }
-
-        /*
-         * Has there been an error received yet?  If not, remember it.
-         * By RFC 2246, we don't bother waiting for a response.
-         * Fatal errors require immediate shutdown.
-         */
-        if (closeReason == null) {
-            /*
-             * Try to clear the kernel buffer to avoid TCP connection resets.
-             */
-            if (oldState == cs_HANDSHAKE) {
-                sockInput.skip(sockInput.available());
-            }
-
-            // If the description equals -1, the alert won't be sent to peer.
-            if (description != -1) {
-                sendAlert(Alerts.alert_fatal, description);
-            }
-            if (cause instanceof SSLException) { // only true if != null
-                closeReason = (SSLException)cause;
-            } else {
-                closeReason =
-                    Alerts.getSSLException(description, cause, diagnostic);
-            }
-        }
-
-        /*
-         * Clean up our side.
-         */
-        closeSocket();
-        // Another thread may have disposed the ciphers during closing
-        if (connectionState < cs_CLOSED) {
-            connectionState = (oldState == cs_APP_CLOSED) ? cs_APP_CLOSED
-                                                              : cs_CLOSED;
-
-            // We should lock readLock and writeLock if no deadlock risks.
-            // See comment in changeReadCiphers()
-            readCipher.dispose();
-            writeCipher.dispose();
-        }
-
-        throw closeReason;
-    }
-
-
-    /*
-     * Process an incoming alert ... caller must already have synchronized
-     * access to "this".
-     */
-    private void recvAlert(InputRecord r) throws IOException {
-        byte level = (byte)r.read();
-        byte description = (byte)r.read();
-        if (description == -1) { // check for short message
-            fatal(Alerts.alert_illegal_parameter, "Short alert message");
-        }
-
-        if (debug != null && (Debug.isOn("record") ||
-                Debug.isOn("handshake"))) {
-            synchronized (System.out) {
-                System.out.print(threadName());
-                System.out.print(", RECV " + protocolVersion + " ALERT:  ");
-                if (level == Alerts.alert_fatal) {
-                    System.out.print("fatal, ");
-                } else if (level == Alerts.alert_warning) {
-                    System.out.print("warning, ");
-                } else {
-                    System.out.print("<level " + (0x0ff & level) + ">, ");
-                }
-                System.out.println(Alerts.alertDescription(description));
-            }
-        }
-
-        if (level == Alerts.alert_warning) {
-            if (description == Alerts.alert_close_notify) {
-                if (connectionState == cs_HANDSHAKE) {
-                    fatal(Alerts.alert_unexpected_message,
-                                "Received close_notify during handshake");
-                } else {
-                    closeInternal(false);  // reply to close
-                }
-            } else {
-
-                //
-                // The other legal warnings relate to certificates,
-                // e.g. no_certificate, bad_certificate, etc; these
-                // are important to the handshaking code, which can
-                // also handle illegal protocol alerts if needed.
-                //
-                if (handshaker != null) {
-                    handshaker.handshakeAlert(description);
-                }
-            }
-        } else { // fatal or unknown level
-            String reason = "Received fatal alert: "
-                + Alerts.alertDescription(description);
-            if (closeReason == null) {
-                closeReason = Alerts.getSSLException(description, reason);
-            }
-            fatal(Alerts.alert_unexpected_message, reason);
-        }
-    }
-
-
-    /*
-     * Emit alerts.  Caller must have synchronized with "this".
-     */
-    private void sendAlert(byte level, byte description) {
-        // the connectionState cannot be cs_START
-        if (connectionState >= cs_SENT_CLOSE) {
-            return;
-        }
-
-        // For initial handshaking, don't send alert message to peer if
-        // handshaker has not started.
-        if (connectionState == cs_HANDSHAKE &&
-            (handshaker == null || !handshaker.started())) {
-            return;
-        }
-
-        OutputRecord r = new OutputRecord(Record.ct_alert);
-        r.setVersion(protocolVersion);
-
-        boolean useDebug = debug != null && Debug.isOn("ssl");
-        if (useDebug) {
-            synchronized (System.out) {
-                System.out.print(threadName());
-                System.out.print(", SEND " + protocolVersion + " ALERT:  ");
-                if (level == Alerts.alert_fatal) {
-                    System.out.print("fatal, ");
-                } else if (level == Alerts.alert_warning) {
-                    System.out.print("warning, ");
-                } else {
-                    System.out.print("<level = " + (0x0ff & level) + ">, ");
-                }
-                System.out.println("description = "
-                        + Alerts.alertDescription(description));
-            }
-        }
-
-        r.write(level);
-        r.write(description);
-        try {
-            writeRecord(r);
-        } catch (IOException e) {
-            if (useDebug) {
-                System.out.println(threadName() +
-                    ", Exception sending alert: " + e);
-            }
-        }
-    }
-
-    //
-    // VARIOUS OTHER METHODS
-    //
-
-    /*
-     * When a connection finishes handshaking by enabling use of a newly
-     * negotiated session, each end learns about it in two halves (read,
-     * and write).  When both read and write ciphers have changed, and the
-     * last handshake message has been read, the connection has joined
-     * (rejoined) the new session.
-     *
-     * NOTE:  The SSLv3 spec is rather unclear on the concepts here.
-     * Sessions don't change once they're established (including cipher
-     * suite and master secret) but connections can join them (and leave
-     * them).  They're created by handshaking, though sometime handshaking
-     * causes connections to join up with pre-established sessions.
-     */
-    private void changeReadCiphers() throws SSLException {
-        if (connectionState != cs_HANDSHAKE
-                && connectionState != cs_RENEGOTIATE) {
-            throw new SSLProtocolException(
-                "State error, change cipher specs");
-        }
-
-        // ... create decompressor
-
-        CipherBox oldCipher = readCipher;
-
-        try {
-            readCipher = handshaker.newReadCipher();
-            readMAC = handshaker.newReadMAC();
-        } catch (GeneralSecurityException e) {
-            // "can't happen"
-            throw (SSLException)new SSLException
-                                ("Algorithm missing:  ").initCause(e);
-        }
-
-        /*
-         * Dispose of any intermediate state in the underlying cipher.
-         * For PKCS11 ciphers, this will release any attached sessions,
-         * and thus make finalization faster.
-         *
-         * Since MAC's doFinal() is called for every SSL/TLS packet, it's
-         * not necessary to do the same with MAC's.
-         */
-        oldCipher.dispose();
-    }
-
-    // used by Handshaker
-    void changeWriteCiphers() throws SSLException {
-        if (connectionState != cs_HANDSHAKE
-                && connectionState != cs_RENEGOTIATE) {
-            throw new SSLProtocolException(
-                "State error, change cipher specs");
-        }
-
-        // ... create compressor
-
-        CipherBox oldCipher = writeCipher;
-
-        try {
-            writeCipher = handshaker.newWriteCipher();
-            writeMAC = handshaker.newWriteMAC();
-        } catch (GeneralSecurityException e) {
-            // "can't happen"
-            throw (SSLException)new SSLException
-                                ("Algorithm missing:  ").initCause(e);
-        }
-
-        // See comment above.
-        oldCipher.dispose();
-
-        // reset the flag of the first application record
-        isFirstAppOutputRecord = true;
-    }
-
-    /*
-     * Updates the SSL version associated with this connection.
-     * Called from Handshaker once it has determined the negotiated version.
-     */
-    synchronized void setVersion(ProtocolVersion protocolVersion) {
-        this.protocolVersion = protocolVersion;
-        output.r.setVersion(protocolVersion);
-    }
-
-    synchronized String getHost() {
-        // Note that the host may be null or empty for localhost.
-        if (host == null || host.length() == 0) {
-            host = getInetAddress().getHostName();
-        }
-        return host;
-    }
-
-    synchronized String getRawHostname() {
-        return rawHostname;
-    }
-
-    // ONLY used by HttpsClient to setup the URI specified hostname
-    synchronized public void setHost(String host) {
-        this.host = host;
-        this.rawHostname = host;
-    }
-
-    /**
-     * Gets an input stream to read from the peer on the other side.
-     * Data read from this stream was always integrity protected in
-     * transit, and will usually have been confidentiality protected.
-     */
-    synchronized public InputStream getInputStream() throws IOException {
-        if (isClosed()) {
-            throw new SocketException("Socket is closed");
-        }
-
-        /*
-         * Can't call isConnected() here, because the Handshakers
-         * do some initialization before we actually connect.
-         */
-        if (connectionState == cs_START) {
-            throw new SocketException("Socket is not connected");
-        }
-
-        return input;
-    }
-
-    /**
-     * Gets an output stream to write to the peer on the other side.
-     * Data written on this stream is always integrity protected, and
-     * will usually be confidentiality protected.
-     */
-    synchronized public OutputStream getOutputStream() throws IOException {
-        if (isClosed()) {
-            throw new SocketException("Socket is closed");
-        }
-
-        /*
-         * Can't call isConnected() here, because the Handshakers
-         * do some initialization before we actually connect.
-         */
-        if (connectionState == cs_START) {
-            throw new SocketException("Socket is not connected");
-        }
-
-        return output;
-    }
-
-    /**
-     * Returns the the SSL Session in use by this connection.  These can
-     * be long lived, and frequently correspond to an entire login session
-     * for some user.
-     */
-    public SSLSession getSession() {
-        /*
-         * Force a synchronous handshake, if appropriate.
-         */
-        if (getConnectionState() == cs_HANDSHAKE) {
-            try {
-                // start handshaking, if failed, the connection will be closed.
-                startHandshake(false);
-            } catch (IOException e) {
-                // handshake failed. log and return a nullSession
-                if (debug != null && Debug.isOn("handshake")) {
-                      System.out.println(threadName() +
-                          ", IOException in getSession():  " + e);
-                }
-            }
-        }
-        synchronized (this) {
-            return sess;
-        }
-    }
-
-    @Override
-    synchronized public SSLSession getHandshakeSession() {
-        return handshakeSession;
-    }
-
-    synchronized void setHandshakeSession(SSLSessionImpl session) {
-        handshakeSession = session;
-    }
-
-    /**
-     * Controls whether new connections may cause creation of new SSL
-     * sessions.
-     *
-     * As long as handshaking has not started, we can change
-     * whether we enable session creations.  Otherwise,
-     * we will need to wait for the next handshake.
-     */
-    synchronized public void setEnableSessionCreation(boolean flag) {
-        enableSessionCreation = flag;
-
-        if ((handshaker != null) && !handshaker.activated()) {
-            handshaker.setEnableSessionCreation(enableSessionCreation);
-        }
-    }
-
-    /**
-     * Returns true if new connections may cause creation of new SSL
-     * sessions.
-     */
-    synchronized public boolean getEnableSessionCreation() {
-        return enableSessionCreation;
-    }
-
-
-    /**
-     * Sets the flag controlling whether a server mode socket
-     * *REQUIRES* SSL client authentication.
-     *
-     * As long as handshaking has not started, we can change
-     * whether client authentication is needed.  Otherwise,
-     * we will need to wait for the next handshake.
-     */
-    synchronized public void setNeedClientAuth(boolean flag) {
-        doClientAuth = (flag ?
-            SSLEngineImpl.clauth_required : SSLEngineImpl.clauth_none);
-
-        if ((handshaker != null) &&
-                (handshaker instanceof ServerHandshaker) &&
-                !handshaker.activated()) {
-            ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
-        }
-    }
-
-    synchronized public boolean getNeedClientAuth() {
-        return (doClientAuth == SSLEngineImpl.clauth_required);
-    }
-
-    /**
-     * Sets the flag controlling whether a server mode socket
-     * *REQUESTS* SSL client authentication.
-     *
-     * As long as handshaking has not started, we can change
-     * whether client authentication is requested.  Otherwise,
-     * we will need to wait for the next handshake.
-     */
-    synchronized public void setWantClientAuth(boolean flag) {
-        doClientAuth = (flag ?
-            SSLEngineImpl.clauth_requested : SSLEngineImpl.clauth_none);
-
-        if ((handshaker != null) &&
-                (handshaker instanceof ServerHandshaker) &&
-                !handshaker.activated()) {
-            ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
-        }
-    }
-
-    synchronized public boolean getWantClientAuth() {
-        return (doClientAuth == SSLEngineImpl.clauth_requested);
-    }
-
-
-    /**
-     * Sets the flag controlling whether the socket is in SSL
-     * client or server mode.  Must be called before any SSL
-     * traffic has started.
-     */
-    synchronized public void setUseClientMode(boolean flag) {
-        switch (connectionState) {
-
-        case cs_START:
-            /*
-             * If we need to change the socket mode and the enabled
-             * protocols haven't specifically been set by the user,
-             * change them to the corresponding default ones.
-             */
-            if (roleIsServer != (!flag) &&
-                    sslContext.isDefaultProtocolList(enabledProtocols)) {
-                enabledProtocols = sslContext.getDefaultProtocolList(!flag);
-            }
-            roleIsServer = !flag;
-            break;
-
-        case cs_HANDSHAKE:
-            /*
-             * If we have a handshaker, but haven't started
-             * SSL traffic, we can throw away our current
-             * handshaker, and start from scratch.  Don't
-             * need to call doneConnect() again, we already
-             * have the streams.
-             */
-            assert(handshaker != null);
-            if (!handshaker.activated()) {
-                /*
-                 * If we need to change the socket mode and the enabled
-                 * protocols haven't specifically been set by the user,
-                 * change them to the corresponding default ones.
-                 */
-                if (roleIsServer != (!flag) &&
-                        sslContext.isDefaultProtocolList(enabledProtocols)) {
-                    enabledProtocols = sslContext.getDefaultProtocolList(!flag);
-                }
-                roleIsServer = !flag;
-                connectionState = cs_START;
-                initHandshaker();
-                break;
-            }
-
-            // If handshake has started, that's an error.  Fall through...
-
-        default:
-            if (debug != null && Debug.isOn("ssl")) {
-                System.out.println(threadName() +
-                    ", setUseClientMode() invoked in state = " +
-                    connectionState);
-            }
-            throw new IllegalArgumentException(
-                "Cannot change mode after SSL traffic has started");
-        }
-    }
-
-    synchronized public boolean getUseClientMode() {
-        return !roleIsServer;
-    }
-
-
-    /**
-     * Returns the names of the cipher suites which could be enabled for use
-     * on an SSL connection.  Normally, only a subset of these will actually
-     * be enabled by default, since this list may include cipher suites which
-     * do not support the mutual authentication of servers and clients, or
-     * which do not protect data confidentiality.  Servers may also need
-     * certain kinds of certificates to use certain cipher suites.
-     *
-     * @return an array of cipher suite names
-     */
-    public String[] getSupportedCipherSuites() {
-        return sslContext.getSupportedCipherSuiteList().toStringArray();
-    }
-
-    /**
-     * Controls which particular cipher suites are enabled for use on
-     * this connection.  The cipher suites must have been listed by
-     * getCipherSuites() as being supported.  Even if a suite has been
-     * enabled, it might never be used if no peer supports it or the
-     * requisite certificates (and private keys) are not available.
-     *
-     * @param suites Names of all the cipher suites to enable.
-     */
-    synchronized public void setEnabledCipherSuites(String[] suites) {
-        enabledCipherSuites = new CipherSuiteList(suites);
-        if ((handshaker != null) && !handshaker.activated()) {
-            handshaker.setEnabledCipherSuites(enabledCipherSuites);
-        }
-    }
-
-    /**
-     * Returns the names of the SSL cipher suites which are currently enabled
-     * for use on this connection.  When an SSL socket is first created,
-     * all enabled cipher suites <em>(a)</em> protect data confidentiality,
-     * by traffic encryption, and <em>(b)</em> can mutually authenticate
-     * both clients and servers.  Thus, in some environments, this value
-     * might be empty.
-     *
-     * @return an array of cipher suite names
-     */
-    synchronized public String[] getEnabledCipherSuites() {
-        return enabledCipherSuites.toStringArray();
-    }
-
-
-    /**
-     * Returns the protocols that are supported by this implementation.
-     * A subset of the supported protocols may be enabled for this connection
-     * @return an array of protocol names.
-     */
-    public String[] getSupportedProtocols() {
-        return sslContext.getSuportedProtocolList().toStringArray();
-    }
-
-    /**
-     * Controls which protocols are enabled for use on
-     * this connection.  The protocols must have been listed by
-     * getSupportedProtocols() as being supported.
-     *
-     * @param protocols protocols to enable.
-     * @exception IllegalArgumentException when one of the protocols
-     *  named by the parameter is not supported.
-     */
-    synchronized public void setEnabledProtocols(String[] protocols) {
-        enabledProtocols = new ProtocolList(protocols);
-        if ((handshaker != null) && !handshaker.activated()) {
-            handshaker.setEnabledProtocols(enabledProtocols);
-        }
-    }
-
-    synchronized public String[] getEnabledProtocols() {
-        return enabledProtocols.toStringArray();
-    }
-
-    /**
-     * Assigns the socket timeout.
-     * @see java.net.Socket#setSoTimeout
-     */
-    public void setSoTimeout(int timeout) throws SocketException {
-        if ((debug != null) && Debug.isOn("ssl")) {
-            System.out.println(threadName() +
-                ", setSoTimeout(" + timeout + ") called");
-        }
-        if (self == this) {
-            super.setSoTimeout(timeout);
-        } else {
-            self.setSoTimeout(timeout);
-        }
-    }
-
-    /**
-     * Registers an event listener to receive notifications that an
-     * SSL handshake has completed on this connection.
-     */
-    public synchronized void addHandshakeCompletedListener(
-            HandshakeCompletedListener listener) {
-        if (listener == null) {
-            throw new IllegalArgumentException("listener is null");
-        }
-        if (handshakeListeners == null) {
-            handshakeListeners = new
-                HashMap<HandshakeCompletedListener, AccessControlContext>(4);
-        }
-        handshakeListeners.put(listener, AccessController.getContext());
-    }
-
-
-    /**
-     * Removes a previously registered handshake completion listener.
-     */
-    public synchronized void removeHandshakeCompletedListener(
-            HandshakeCompletedListener listener) {
-        if (handshakeListeners == null) {
-            throw new IllegalArgumentException("no listeners");
-        }
-        if (handshakeListeners.remove(listener) == null) {
-            throw new IllegalArgumentException("listener not registered");
-        }
-        if (handshakeListeners.isEmpty()) {
-            handshakeListeners = null;
-        }
-    }
-
-    /**
-     * Returns the SSLParameters in effect for this SSLSocket.
-     */
-    synchronized public SSLParameters getSSLParameters() {
-        SSLParameters params = super.getSSLParameters();
-
-        // the super implementation does not handle the following parameters
-        params.setEndpointIdentificationAlgorithm(identificationProtocol);
-        params.setAlgorithmConstraints(algorithmConstraints);
-
-        return params;
-    }
-
-    /**
-     * Applies SSLParameters to this socket.
-     */
-    synchronized public void setSSLParameters(SSLParameters params) {
-        super.setSSLParameters(params);
-
-        // the super implementation does not handle the following parameters
-        identificationProtocol = params.getEndpointIdentificationAlgorithm();
-        algorithmConstraints = params.getAlgorithmConstraints();
-        if ((handshaker != null) && !handshaker.started()) {
-            handshaker.setIdentificationProtocol(identificationProtocol);
-            handshaker.setAlgorithmConstraints(algorithmConstraints);
-        }
-    }
-
-    //
-    // We allocate a separate thread to deliver handshake completion
-    // events.  This ensures that the notifications don't block the
-    // protocol state machine.
-    //
-    private static class NotifyHandshakeThread extends Thread {
-
-        private Set<Map.Entry<HandshakeCompletedListener,AccessControlContext>>
-                targets;        // who gets notified
-        private HandshakeCompletedEvent event;          // the notification
-
-        NotifyHandshakeThread(
-            Set<Map.Entry<HandshakeCompletedListener,AccessControlContext>>
-            entrySet, HandshakeCompletedEvent e) {
-
-            super("HandshakeCompletedNotify-Thread");
-            targets = new HashSet<>(entrySet);          // clone the entry set
-            event = e;
-        }
-
-        public void run() {
-            // Don't need to synchronize, as it only runs in one thread.
-            for (Map.Entry<HandshakeCompletedListener,AccessControlContext>
-                entry : targets) {
-
-                final HandshakeCompletedListener l = entry.getKey();
-                AccessControlContext acc = entry.getValue();
-                AccessController.doPrivileged(new PrivilegedAction<Void>() {
-                    public Void run() {
-                        l.handshakeCompleted(event);
-                        return null;
-                    }
-                }, acc);
-            }
-        }
-    }
-
-    /**
-     * Return the name of the current thread. Utility method.
-     */
-    private static String threadName() {
-        return Thread.currentThread().getName();
-    }
-
-    /**
-     * Returns a printable representation of this end of the connection.
-     */
-    public String toString() {
-        StringBuffer retval = new StringBuffer(80);
-
-        retval.append(Integer.toHexString(hashCode()));
-        retval.append("[");
-        retval.append(sess.getCipherSuite());
-        retval.append(": ");
-
-        if (self == this) {
-            retval.append(super.toString());
-        } else {
-            retval.append(self.toString());
-        }
-        retval.append("]");
-
-        return retval.toString();
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/ServerHandshaker.java b/ojluni/src/main/java/sun/security/ssl/ServerHandshaker.java
deleted file mode 100755
index c651b44..0000000
--- a/ojluni/src/main/java/sun/security/ssl/ServerHandshaker.java
+++ /dev/null
@@ -1,1682 +0,0 @@
-/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.util.*;
-import java.security.*;
-import java.security.cert.*;
-import java.security.interfaces.*;
-import java.security.spec.ECParameterSpec;
-
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-
-import javax.net.ssl.*;
-
-import javax.security.auth.Subject;
-
-import sun.security.ssl.HandshakeMessage.*;
-import sun.security.ssl.CipherSuite.*;
-import sun.security.ssl.SignatureAndHashAlgorithm.*;
-import static sun.security.ssl.CipherSuite.*;
-import static sun.security.ssl.CipherSuite.KeyExchange.*;
-
-/**
- * ServerHandshaker does the protocol handshaking from the point
- * of view of a server.  It is driven asychronously by handshake messages
- * as delivered by the parent Handshaker class, and also uses
- * common functionality (e.g. key generation) that is provided there.
- *
- * @author David Brownell
- */
-final class ServerHandshaker extends Handshaker {
-
-    // is the server going to require the client to authenticate?
-    private byte                doClientAuth;
-
-    // our authentication info
-    private X509Certificate[]   certs;
-    private PrivateKey          privateKey;
-
-    private SecretKey[]       kerberosKeys;
-
-    // flag to check for clientCertificateVerify message
-    private boolean             needClientVerify = false;
-
-    /*
-     * For exportable ciphersuites using non-exportable key sizes, we use
-     * ephemeral RSA keys. We could also do anonymous RSA in the same way
-     * but there are no such ciphersuites currently defined.
-     */
-    private PrivateKey          tempPrivateKey;
-    private PublicKey           tempPublicKey;
-
-    /*
-     * For anonymous and ephemeral Diffie-Hellman key exchange, we use
-     * ephemeral Diffie-Hellman keys.
-     */
-    private DHCrypt dh;
-
-    // Helper for ECDH based key exchanges
-    private ECDHCrypt ecdh;
-
-    // version request by the client in its ClientHello
-    // we remember it for the RSA premaster secret version check
-    private ProtocolVersion clientRequestedVersion;
-
-    private SupportedEllipticCurvesExtension supportedCurves;
-
-    // the preferable signature algorithm used by ServerKeyExchange message
-    SignatureAndHashAlgorithm preferableSignatureAlgorithm;
-
-    /*
-     * Constructor ... use the keys found in the auth context.
-     */
-    ServerHandshaker(SSLSocketImpl socket, SSLContextImpl context,
-            ProtocolList enabledProtocols, byte clientAuth,
-            ProtocolVersion activeProtocolVersion, boolean isInitialHandshake,
-            boolean secureRenegotiation,
-            byte[] clientVerifyData, byte[] serverVerifyData) {
-
-        super(socket, context, enabledProtocols,
-                (clientAuth != SSLEngineImpl.clauth_none), false,
-                activeProtocolVersion, isInitialHandshake, secureRenegotiation,
-                clientVerifyData, serverVerifyData);
-        doClientAuth = clientAuth;
-    }
-
-    /*
-     * Constructor ... use the keys found in the auth context.
-     */
-    ServerHandshaker(SSLEngineImpl engine, SSLContextImpl context,
-            ProtocolList enabledProtocols, byte clientAuth,
-            ProtocolVersion activeProtocolVersion,
-            boolean isInitialHandshake, boolean secureRenegotiation,
-            byte[] clientVerifyData, byte[] serverVerifyData) {
-
-        super(engine, context, enabledProtocols,
-                (clientAuth != SSLEngineImpl.clauth_none), false,
-                activeProtocolVersion, isInitialHandshake, secureRenegotiation,
-                clientVerifyData, serverVerifyData);
-        doClientAuth = clientAuth;
-    }
-
-    /*
-     * As long as handshaking has not started, we can change
-     * whether client authentication is required.  Otherwise,
-     * we will need to wait for the next handshake.
-     */
-    void setClientAuth(byte clientAuth) {
-        doClientAuth = clientAuth;
-    }
-
-    /*
-     * This routine handles all the server side handshake messages, one at
-     * a time.  Given the message type (and in some cases the pending cipher
-     * spec) it parses the type-specific message.  Then it calls a function
-     * that handles that specific message.
-     *
-     * It updates the state machine as each message is processed, and writes
-     * responses as needed using the connection in the constructor.
-     */
-    void processMessage(byte type, int message_len)
-            throws IOException {
-        //
-        // In SSLv3 and TLS, messages follow strictly increasing
-        // numerical order _except_ for one annoying special case.
-        //
-        if ((state >= type)
-                && (state != HandshakeMessage.ht_client_key_exchange
-                    && type != HandshakeMessage.ht_certificate_verify)) {
-            throw new SSLProtocolException(
-                    "Handshake message sequence violation, state = " + state
-                    + ", type = " + type);
-        }
-
-        switch (type) {
-            case HandshakeMessage.ht_client_hello:
-                ClientHello ch = new ClientHello(input, message_len);
-                /*
-                 * send it off for processing.
-                 */
-                this.clientHello(ch);
-                break;
-
-            case HandshakeMessage.ht_certificate:
-                if (doClientAuth == SSLEngineImpl.clauth_none) {
-                    fatalSE(Alerts.alert_unexpected_message,
-                                "client sent unsolicited cert chain");
-                    // NOTREACHED
-                }
-                this.clientCertificate(new CertificateMsg(input));
-                break;
-
-            case HandshakeMessage.ht_client_key_exchange:
-                SecretKey preMasterSecret;
-                switch (keyExchange) {
-                case K_RSA:
-                case K_RSA_EXPORT:
-                    /*
-                     * The client's pre-master secret is decrypted using
-                     * either the server's normal private RSA key, or the
-                     * temporary one used for non-export or signing-only
-                     * certificates/keys.
-                     */
-                    RSAClientKeyExchange pms = new RSAClientKeyExchange(
-                            protocolVersion, clientRequestedVersion,
-                            sslContext.getSecureRandom(), input,
-                            message_len, privateKey);
-                    preMasterSecret = this.clientKeyExchange(pms);
-                    break;
-                case K_KRB5:
-                case K_KRB5_EXPORT:
-                    preMasterSecret = this.clientKeyExchange(
-                        new KerberosClientKeyExchange(protocolVersion,
-                            clientRequestedVersion,
-                            sslContext.getSecureRandom(),
-                            input,
-                            kerberosKeys));
-                    break;
-                case K_DHE_RSA:
-                case K_DHE_DSS:
-                case K_DH_ANON:
-                    /*
-                     * The pre-master secret is derived using the normal
-                     * Diffie-Hellman calculation.   Note that the main
-                     * protocol difference in these five flavors is in how
-                     * the ServerKeyExchange message was constructed!
-                     */
-                    preMasterSecret = this.clientKeyExchange(
-                            new DHClientKeyExchange(input));
-                    break;
-                case K_ECDH_RSA:
-                case K_ECDH_ECDSA:
-                case K_ECDHE_RSA:
-                case K_ECDHE_ECDSA:
-                case K_ECDH_ANON:
-                    preMasterSecret = this.clientKeyExchange
-                                            (new ECDHClientKeyExchange(input));
-                    break;
-                default:
-                    throw new SSLProtocolException
-                        ("Unrecognized key exchange: " + keyExchange);
-                }
-
-                //
-                // All keys are calculated from the premaster secret
-                // and the exchanged nonces in the same way.
-                //
-                calculateKeys(preMasterSecret, clientRequestedVersion);
-                break;
-
-            case HandshakeMessage.ht_certificate_verify:
-                this.clientCertificateVerify(new CertificateVerify(input,
-                            localSupportedSignAlgs, protocolVersion));
-                break;
-
-            case HandshakeMessage.ht_finished:
-                this.clientFinished(
-                    new Finished(protocolVersion, input, cipherSuite));
-                break;
-
-            default:
-                throw new SSLProtocolException(
-                        "Illegal server handshake msg, " + type);
-        }
-
-        //
-        // Move state machine forward if the message handling
-        // code didn't already do so
-        //
-        if (state < type) {
-            if(type == HandshakeMessage.ht_certificate_verify) {
-                state = type + 2;    // an annoying special case
-            } else {
-                state = type;
-            }
-        }
-    }
-
-
-    /*
-     * ClientHello presents the server with a bunch of options, to which the
-     * server replies with a ServerHello listing the ones which this session
-     * will use.  If needed, it also writes its Certificate plus in some cases
-     * a ServerKeyExchange message.  It may also write a CertificateRequest,
-     * to elicit a client certificate.
-     *
-     * All these messages are terminated by a ServerHelloDone message.  In
-     * most cases, all this can be sent in a single Record.
-     */
-    private void clientHello(ClientHello mesg) throws IOException {
-        if (debug != null && Debug.isOn("handshake")) {
-            mesg.print(System.out);
-        }
-
-        // Does the message include security renegotiation indication?
-        boolean renegotiationIndicated = false;
-
-        // check the TLS_EMPTY_RENEGOTIATION_INFO_SCSV
-        CipherSuiteList cipherSuites = mesg.getCipherSuites();
-        if (cipherSuites.contains(CipherSuite.C_SCSV)) {
-            renegotiationIndicated = true;
-            if (isInitialHandshake) {
-                secureRenegotiation = true;
-            } else {
-                // abort the handshake with a fatal handshake_failure alert
-                if (secureRenegotiation) {
-                    fatalSE(Alerts.alert_handshake_failure,
-                        "The SCSV is present in a secure renegotiation");
-                } else {
-                    fatalSE(Alerts.alert_handshake_failure,
-                        "The SCSV is present in a insecure renegotiation");
-                }
-            }
-        }
-
-        // check the "renegotiation_info" extension
-        RenegotiationInfoExtension clientHelloRI = (RenegotiationInfoExtension)
-                    mesg.extensions.get(ExtensionType.EXT_RENEGOTIATION_INFO);
-        if (clientHelloRI != null) {
-            renegotiationIndicated = true;
-            if (isInitialHandshake) {
-                // verify the length of the "renegotiated_connection" field
-                if (!clientHelloRI.isEmpty()) {
-                    // abort the handshake with a fatal handshake_failure alert
-                    fatalSE(Alerts.alert_handshake_failure,
-                        "The renegotiation_info field is not empty");
-                }
-
-                secureRenegotiation = true;
-            } else {
-                if (!secureRenegotiation) {
-                    // unexpected RI extension for insecure renegotiation,
-                    // abort the handshake with a fatal handshake_failure alert
-                    fatalSE(Alerts.alert_handshake_failure,
-                        "The renegotiation_info is present in a insecure " +
-                        "renegotiation");
-                }
-
-                // verify the client_verify_data value
-                if (!Arrays.equals(clientVerifyData,
-                                clientHelloRI.getRenegotiatedConnection())) {
-                    fatalSE(Alerts.alert_handshake_failure,
-                        "Incorrect verify data in ClientHello " +
-                        "renegotiation_info message");
-                }
-            }
-        } else if (!isInitialHandshake && secureRenegotiation) {
-           // if the connection's "secure_renegotiation" flag is set to TRUE
-           // and the "renegotiation_info" extension is not present, abort
-           // the handshake.
-            fatalSE(Alerts.alert_handshake_failure,
-                        "Inconsistent secure renegotiation indication");
-        }
-
-        // if there is no security renegotiation indication or the previous
-        // handshake is insecure.
-        if (!renegotiationIndicated || !secureRenegotiation) {
-            if (isInitialHandshake) {
-                if (!allowLegacyHelloMessages) {
-                    // abort the handshake with a fatal handshake_failure alert
-                    fatalSE(Alerts.alert_handshake_failure,
-                        "Failed to negotiate the use of secure renegotiation");
-                }
-
-                // continue with legacy ClientHello
-                if (debug != null && Debug.isOn("handshake")) {
-                    System.out.println("Warning: No renegotiation " +
-                        "indication in ClientHello, allow legacy ClientHello");
-                }
-            } else if (!allowUnsafeRenegotiation) {
-                // abort the handshake
-                if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) {
-                    // response with a no_renegotiation warning,
-                    warningSE(Alerts.alert_no_renegotiation);
-
-                    // invalidate the handshake so that the caller can
-                    // dispose this object.
-                    invalidated = true;
-
-                    // If there is still unread block in the handshake
-                    // input stream, it would be truncated with the disposal
-                    // and the next handshake message will become incomplete.
-                    //
-                    // However, according to SSL/TLS specifications, no more
-                    // handshake message could immediately follow ClientHello
-                    // or HelloRequest. But in case of any improper messages,
-                    // we'd better check to ensure there is no remaining bytes
-                    // in the handshake input stream.
-                    if (input.available() > 0) {
-                        fatalSE(Alerts.alert_unexpected_message,
-                            "ClientHello followed by an unexpected  " +
-                            "handshake message");
-                    }
-
-                    return;
-                } else {
-                    // For SSLv3, send the handshake_failure fatal error.
-                    // Note that SSLv3 does not define a no_renegotiation
-                    // alert like TLSv1. However we cannot ignore the message
-                    // simply, otherwise the other side was waiting for a
-                    // response that would never come.
-                    fatalSE(Alerts.alert_handshake_failure,
-                        "Renegotiation is not allowed");
-                }
-            } else {   // !isInitialHandshake && allowUnsafeRenegotiation
-                // continue with unsafe renegotiation.
-                if (debug != null && Debug.isOn("handshake")) {
-                    System.out.println(
-                            "Warning: continue with insecure renegotiation");
-                }
-            }
-        }
-
-        /*
-         * Always make sure this entire record has been digested before we
-         * start emitting output, to ensure correct digesting order.
-         */
-        input.digestNow();
-
-        /*
-         * FIRST, construct the ServerHello using the options and priorities
-         * from the ClientHello.  Update the (pending) cipher spec as we do
-         * so, and save the client's version to protect against rollback
-         * attacks.
-         *
-         * There are a bunch of minor tasks here, and one major one: deciding
-         * if the short or the full handshake sequence will be used.
-         */
-        ServerHello m1 = new ServerHello();
-
-        clientRequestedVersion = mesg.protocolVersion;
-
-        // select a proper protocol version.
-        ProtocolVersion selectedVersion =
-               selectProtocolVersion(clientRequestedVersion);
-        if (selectedVersion == null ||
-                selectedVersion.v == ProtocolVersion.SSL20Hello.v) {
-            fatalSE(Alerts.alert_handshake_failure,
-                "Client requested protocol " + clientRequestedVersion +
-                " not enabled or not supported");
-        }
-
-        handshakeHash.protocolDetermined(selectedVersion);
-        setVersion(selectedVersion);
-
-        m1.protocolVersion = protocolVersion;
-
-        //
-        // random ... save client and server values for later use
-        // in computing the master secret (from pre-master secret)
-        // and thence the other crypto keys.
-        //
-        // NOTE:  this use of three inputs to generating _each_ set
-        // of ciphers slows things down, but it does increase the
-        // security since each connection in the session can hold
-        // its own authenticated (and strong) keys.  One could make
-        // creation of a session a rare thing...
-        //
-        clnt_random = mesg.clnt_random;
-        svr_random = new RandomCookie(sslContext.getSecureRandom());
-        m1.svr_random = svr_random;
-
-        session = null; // forget about the current session
-        //
-        // Here we go down either of two paths:  (a) the fast one, where
-        // the client's asked to rejoin an existing session, and the server
-        // permits this; (b) the other one, where a new session is created.
-        //
-        if (mesg.sessionId.length() != 0) {
-            // client is trying to resume a session, let's see...
-
-            SSLSessionImpl previous = ((SSLSessionContextImpl)sslContext
-                        .engineGetServerSessionContext())
-                        .get(mesg.sessionId.getId());
-            //
-            // Check if we can use the fast path, resuming a session.  We
-            // can do so iff we have a valid record for that session, and
-            // the cipher suite for that session was on the list which the
-            // client requested, and if we're not forgetting any needed
-            // authentication on the part of the client.
-            //
-            if (previous != null) {
-                resumingSession = previous.isRejoinable();
-
-                if (resumingSession) {
-                    ProtocolVersion oldVersion = previous.getProtocolVersion();
-                    // cannot resume session with different version
-                    if (oldVersion != protocolVersion) {
-                        resumingSession = false;
-                    }
-                }
-
-                if (resumingSession &&
-                        (doClientAuth == SSLEngineImpl.clauth_required)) {
-                    try {
-                        previous.getPeerPrincipal();
-                    } catch (SSLPeerUnverifiedException e) {
-                        resumingSession = false;
-                    }
-                }
-
-                // validate subject identity
-                if (resumingSession) {
-                    CipherSuite suite = previous.getSuite();
-                    if (suite.keyExchange == K_KRB5 ||
-                        suite.keyExchange == K_KRB5_EXPORT) {
-                        Principal localPrincipal = previous.getLocalPrincipal();
-
-                        Subject subject = null;
-                        try {
-                            subject = AccessController.doPrivileged(
-                                new PrivilegedExceptionAction<Subject>() {
-                                public Subject run() throws Exception {
-                                    return
-                                        Krb5Helper.getServerSubject(getAccSE());
-                            }});
-                        } catch (PrivilegedActionException e) {
-                            subject = null;
-                            if (debug != null && Debug.isOn("session")) {
-                                System.out.println("Attempt to obtain" +
-                                                " subject failed!");
-                            }
-                        }
-
-                        if (subject != null) {
-                            // Eliminate dependency on KerberosPrincipal
-                            Set<Principal> principals =
-                                subject.getPrincipals(Principal.class);
-                            if (!principals.contains(localPrincipal)) {
-                                resumingSession = false;
-                                if (debug != null && Debug.isOn("session")) {
-                                    System.out.println("Subject identity" +
-                                                        " is not the same");
-                                }
-                            } else {
-                                if (debug != null && Debug.isOn("session"))
-                                    System.out.println("Subject identity" +
-                                                        " is same");
-                            }
-                        } else {
-                            resumingSession = false;
-                            if (debug != null && Debug.isOn("session"))
-                                System.out.println("Kerberos credentials are" +
-                                    " not present in the current Subject;" +
-                                    " check if " +
-                                    " javax.security.auth.useSubjectAsCreds" +
-                                    " system property has been set to false");
-                        }
-                    }
-                }
-
-                if (resumingSession) {
-                    CipherSuite suite = previous.getSuite();
-                    // verify that the ciphersuite from the cached session
-                    // is in the list of client requested ciphersuites and
-                    // we have it enabled
-                    if ((isNegotiable(suite) == false) ||
-                            (mesg.getCipherSuites().contains(suite) == false)) {
-                        resumingSession = false;
-                    } else {
-                        // everything looks ok, set the ciphersuite
-                        // this should be done last when we are sure we
-                        // will resume
-                        setCipherSuite(suite);
-                    }
-                }
-
-                if (resumingSession) {
-                    session = previous;
-                    if (debug != null &&
-                        (Debug.isOn("handshake") || Debug.isOn("session"))) {
-                        System.out.println("%% Resuming " + session);
-                    }
-                }
-            }
-        } // else client did not try to resume
-
-        //
-        // If client hasn't specified a session we can resume, start a
-        // new one and choose its cipher suite and compression options.
-        // Unless new session creation is disabled for this connection!
-        //
-        if (session == null) {
-            if (!enableNewSession) {
-                throw new SSLException("Client did not resume a session");
-            }
-
-            supportedCurves = (SupportedEllipticCurvesExtension)
-                        mesg.extensions.get(ExtensionType.EXT_ELLIPTIC_CURVES);
-
-            // We only need to handle the "signature_algorithm" extension
-            // for full handshakes and TLS 1.2 or later.
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                SignatureAlgorithmsExtension signAlgs =
-                    (SignatureAlgorithmsExtension)mesg.extensions.get(
-                                    ExtensionType.EXT_SIGNATURE_ALGORITHMS);
-                if (signAlgs != null) {
-                    Collection<SignatureAndHashAlgorithm> peerSignAlgs =
-                                            signAlgs.getSignAlgorithms();
-                    if (peerSignAlgs == null || peerSignAlgs.isEmpty()) {
-                        throw new SSLHandshakeException(
-                            "No peer supported signature algorithms");
-                    }
-
-                    Collection<SignatureAndHashAlgorithm>
-                        supportedPeerSignAlgs =
-                            SignatureAndHashAlgorithm.getSupportedAlgorithms(
-                                                            peerSignAlgs);
-                    if (supportedPeerSignAlgs.isEmpty()) {
-                        throw new SSLHandshakeException(
-                            "No supported signature and hash algorithm " +
-                            "in common");
-                    }
-
-                    setPeerSupportedSignAlgs(supportedPeerSignAlgs);
-                } // else, need to use peer implicit supported signature algs
-            }
-
-            session = new SSLSessionImpl(protocolVersion, CipherSuite.C_NULL,
-                        getLocalSupportedSignAlgs(),
-                        sslContext.getSecureRandom(),
-                        getHostAddressSE(), getPortSE());
-
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                if (peerSupportedSignAlgs != null) {
-                    session.setPeerSupportedSignatureAlgorithms(
-                            peerSupportedSignAlgs);
-                }   // else, we will set the implicit peer supported signature
-                    // algorithms in chooseCipherSuite()
-            }
-
-            // set the handshake session
-            setHandshakeSessionSE(session);
-
-            // choose cipher suite and corresponding private key
-            chooseCipherSuite(mesg);
-
-            session.setSuite(cipherSuite);
-            session.setLocalPrivateKey(privateKey);
-
-            // chooseCompression(mesg);
-        } else {
-            // set the handshake session
-            setHandshakeSessionSE(session);
-        }
-
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            if (resumingSession) {
-                handshakeHash.setCertificateVerifyAlg(null);
-            }
-            handshakeHash.setFinishedAlg(cipherSuite.prfAlg.getPRFHashAlg());
-        }
-
-        m1.cipherSuite = cipherSuite;
-        m1.sessionId = session.getSessionId();
-        m1.compression_method = session.getCompression();
-
-        if (secureRenegotiation) {
-            // For ServerHellos that are initial handshakes, then the
-            // "renegotiated_connection" field in "renegotiation_info"
-            // extension is of zero length.
-            //
-            // For ServerHellos that are renegotiating, this field contains
-            // the concatenation of client_verify_data and server_verify_data.
-            //
-            // Note that for initial handshakes, both the clientVerifyData
-            // variable and serverVerifyData variable are of zero length.
-            HelloExtension serverHelloRI = new RenegotiationInfoExtension(
-                                        clientVerifyData, serverVerifyData);
-            m1.extensions.add(serverHelloRI);
-        }
-
-        if (debug != null && Debug.isOn("handshake")) {
-            m1.print(System.out);
-            System.out.println("Cipher suite:  " + session.getSuite());
-        }
-        m1.write(output);
-
-        //
-        // If we are resuming a session, we finish writing handshake
-        // messages right now and then finish.
-        //
-        if (resumingSession) {
-            calculateConnectionKeys(session.getMasterSecret());
-            sendChangeCipherAndFinish(false);
-            return;
-        }
-
-
-        /*
-         * SECOND, write the server Certificate(s) if we need to.
-         *
-         * NOTE:  while an "anonymous RSA" mode is explicitly allowed by
-         * the protocol, we can't support it since all of the SSL flavors
-         * defined in the protocol spec are explicitly stated to require
-         * using RSA certificates.
-         */
-        if (keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
-            // Server certificates are omitted for Kerberos ciphers
-
-        } else if ((keyExchange != K_DH_ANON) && (keyExchange != K_ECDH_ANON)) {
-            if (certs == null) {
-                throw new RuntimeException("no certificates");
-            }
-
-            CertificateMsg m2 = new CertificateMsg(certs);
-
-            /*
-             * Set local certs in the SSLSession, output
-             * debug info, and then actually write to the client.
-             */
-            session.setLocalCertificates(certs);
-            if (debug != null && Debug.isOn("handshake")) {
-                m2.print(System.out);
-            }
-            m2.write(output);
-
-            // XXX has some side effects with OS TCP buffering,
-            // leave it out for now
-
-            // let client verify chain in the meantime...
-            // output.flush();
-        } else {
-            if (certs != null) {
-                throw new RuntimeException("anonymous keyexchange with certs");
-            }
-        }
-
-        /*
-         * THIRD, the ServerKeyExchange message ... iff it's needed.
-         *
-         * It's usually needed unless there's an encryption-capable
-         * RSA cert, or a D-H cert.  The notable exception is that
-         * exportable ciphers used with big RSA keys need to downgrade
-         * to use short RSA keys, even when the key/cert encrypts OK.
-         */
-
-        ServerKeyExchange m3;
-        switch (keyExchange) {
-        case K_RSA:
-        case K_KRB5:
-        case K_KRB5_EXPORT:
-            // no server key exchange for RSA or KRB5 ciphersuites
-            m3 = null;
-            break;
-        case K_RSA_EXPORT:
-            if (JsseJce.getRSAKeyLength(certs[0].getPublicKey()) > 512) {
-                try {
-                    m3 = new RSA_ServerKeyExchange(
-                        tempPublicKey, privateKey,
-                        clnt_random, svr_random,
-                        sslContext.getSecureRandom());
-                    privateKey = tempPrivateKey;
-                } catch (GeneralSecurityException e) {
-                    throwSSLException
-                        ("Error generating RSA server key exchange", e);
-                    m3 = null; // make compiler happy
-                }
-            } else {
-                // RSA_EXPORT with short key, don't need ServerKeyExchange
-                m3 = null;
-            }
-            break;
-        case K_DHE_RSA:
-        case K_DHE_DSS:
-            try {
-                m3 = new DH_ServerKeyExchange(dh,
-                    privateKey,
-                    clnt_random.random_bytes,
-                    svr_random.random_bytes,
-                    sslContext.getSecureRandom(),
-                    preferableSignatureAlgorithm,
-                    protocolVersion);
-            } catch (GeneralSecurityException e) {
-                throwSSLException("Error generating DH server key exchange", e);
-                m3 = null; // make compiler happy
-            }
-            break;
-        case K_DH_ANON:
-            m3 = new DH_ServerKeyExchange(dh, protocolVersion);
-            break;
-        case K_ECDHE_RSA:
-        case K_ECDHE_ECDSA:
-        case K_ECDH_ANON:
-            try {
-                m3 = new ECDH_ServerKeyExchange(ecdh,
-                    privateKey,
-                    clnt_random.random_bytes,
-                    svr_random.random_bytes,
-                    sslContext.getSecureRandom(),
-                    preferableSignatureAlgorithm,
-                    protocolVersion);
-            } catch (GeneralSecurityException e) {
-                throwSSLException(
-                    "Error generating ECDH server key exchange", e);
-                m3 = null; // make compiler happy
-            }
-            break;
-        case K_ECDH_RSA:
-        case K_ECDH_ECDSA:
-            // ServerKeyExchange not used for fixed ECDH
-            m3 = null;
-            break;
-        default:
-            throw new RuntimeException("internal error: " + keyExchange);
-        }
-        if (m3 != null) {
-            if (debug != null && Debug.isOn("handshake")) {
-                m3.print(System.out);
-            }
-            m3.write(output);
-        }
-
-        //
-        // FOURTH, the CertificateRequest message.  The details of
-        // the message can be affected by the key exchange algorithm
-        // in use.  For example, certs with fixed Diffie-Hellman keys
-        // are only useful with the DH_DSS and DH_RSA key exchange
-        // algorithms.
-        //
-        // Needed only if server requires client to authenticate self.
-        // Illegal for anonymous flavors, so we need to check that.
-        //
-        // CertificateRequest is omitted for Kerberos ciphers
-        if (doClientAuth != SSLEngineImpl.clauth_none &&
-                keyExchange != K_DH_ANON && keyExchange != K_ECDH_ANON &&
-                keyExchange != K_KRB5 && keyExchange != K_KRB5_EXPORT) {
-
-            CertificateRequest m4;
-            X509Certificate caCerts[];
-
-            Collection<SignatureAndHashAlgorithm> localSignAlgs = null;
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                // We currently use all local upported signature and hash
-                // algorithms. However, to minimize the computation cost
-                // of requested hash algorithms, we may use a restricted
-                // set of signature algorithms in the future.
-                localSignAlgs = getLocalSupportedSignAlgs();
-                if (localSignAlgs.isEmpty()) {
-                    throw new SSLHandshakeException(
-                            "No supported signature algorithm");
-                }
-
-                Set<String> localHashAlgs =
-                    SignatureAndHashAlgorithm.getHashAlgorithmNames(
-                        localSignAlgs);
-                if (localHashAlgs.isEmpty()) {
-                    throw new SSLHandshakeException(
-                            "No supported signature algorithm");
-                }
-                handshakeHash.restrictCertificateVerifyAlgs(localHashAlgs);
-            }
-
-            caCerts = sslContext.getX509TrustManager().getAcceptedIssuers();
-            m4 = new CertificateRequest(caCerts, keyExchange,
-                                            localSignAlgs, protocolVersion);
-
-            if (debug != null && Debug.isOn("handshake")) {
-                m4.print(System.out);
-            }
-            m4.write(output);
-        } else {
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                handshakeHash.setCertificateVerifyAlg(null);
-            }
-        }
-
-        /*
-         * FIFTH, say ServerHelloDone.
-         */
-        ServerHelloDone m5 = new ServerHelloDone();
-
-        if (debug != null && Debug.isOn("handshake")) {
-            m5.print(System.out);
-        }
-        m5.write(output);
-
-        /*
-         * Flush any buffered messages so the client will see them.
-         * Ideally, all the messages above go in a single network level
-         * message to the client.  Without big Certificate chains, it's
-         * going to be the common case.
-         */
-        output.flush();
-    }
-
-    /*
-     * Choose cipher suite from among those supported by client. Sets
-     * the cipherSuite and keyExchange variables.
-     */
-    private void chooseCipherSuite(ClientHello mesg) throws IOException {
-        for (CipherSuite suite : mesg.getCipherSuites().collection()) {
-            if (isNegotiable(suite) == false) {
-                continue;
-            }
-
-            if (doClientAuth == SSLEngineImpl.clauth_required) {
-                if ((suite.keyExchange == K_DH_ANON) ||
-                    (suite.keyExchange == K_ECDH_ANON)) {
-                    continue;
-                }
-            }
-            if (trySetCipherSuite(suite) == false) {
-                continue;
-            }
-            return;
-        }
-        fatalSE(Alerts.alert_handshake_failure,
-                    "no cipher suites in common");
-    }
-
-    /**
-     * Set the given CipherSuite, if possible. Return the result.
-     * The call succeeds if the CipherSuite is available and we have
-     * the necessary certificates to complete the handshake. We don't
-     * check if the CipherSuite is actually enabled.
-     *
-     * If successful, this method also generates ephemeral keys if
-     * required for this ciphersuite. This may take some time, so this
-     * method should only be called if you really want to use the
-     * CipherSuite.
-     *
-     * This method is called from chooseCipherSuite() in this class.
-     */
-    boolean trySetCipherSuite(CipherSuite suite) {
-        /*
-         * If we're resuming a session we know we can
-         * support this key exchange algorithm and in fact
-         * have already cached the result of it in
-         * the session state.
-         */
-        if (resumingSession) {
-            return true;
-        }
-
-        if (suite.isNegotiable() == false) {
-            return false;
-        }
-
-        // must not negotiate the obsoleted weak cipher suites.
-        if (protocolVersion.v >= suite.obsoleted) {
-            return false;
-        }
-
-        // must not negotiate unsupported cipher suites.
-        if (protocolVersion.v < suite.supported) {
-            return false;
-        }
-
-        KeyExchange keyExchange = suite.keyExchange;
-
-        // null out any existing references
-        privateKey = null;
-        certs = null;
-        dh = null;
-        tempPrivateKey = null;
-        tempPublicKey = null;
-
-        Collection<SignatureAndHashAlgorithm> supportedSignAlgs = null;
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            if (peerSupportedSignAlgs != null) {
-                supportedSignAlgs = peerSupportedSignAlgs;
-            } else {
-                SignatureAndHashAlgorithm algorithm = null;
-
-                // we may optimize the performance
-                switch (keyExchange) {
-                    // If the negotiated key exchange algorithm is one of
-                    // (RSA, DHE_RSA, DH_RSA, RSA_PSK, ECDH_RSA, ECDHE_RSA),
-                    // behave as if client had sent the value {sha1,rsa}.
-                    case K_RSA:
-                    case K_DHE_RSA:
-                    case K_DH_RSA:
-                    // case K_RSA_PSK:
-                    case K_ECDH_RSA:
-                    case K_ECDHE_RSA:
-                        algorithm = SignatureAndHashAlgorithm.valueOf(
-                                HashAlgorithm.SHA1.value,
-                                SignatureAlgorithm.RSA.value, 0);
-                        break;
-                    // If the negotiated key exchange algorithm is one of
-                    // (DHE_DSS, DH_DSS), behave as if the client had
-                    // sent the value {sha1,dsa}.
-                    case K_DHE_DSS:
-                    case K_DH_DSS:
-                        algorithm = SignatureAndHashAlgorithm.valueOf(
-                                HashAlgorithm.SHA1.value,
-                                SignatureAlgorithm.DSA.value, 0);
-                        break;
-                    // If the negotiated key exchange algorithm is one of
-                    // (ECDH_ECDSA, ECDHE_ECDSA), behave as if the client
-                    // had sent value {sha1,ecdsa}.
-                    case K_ECDH_ECDSA:
-                    case K_ECDHE_ECDSA:
-                        algorithm = SignatureAndHashAlgorithm.valueOf(
-                                HashAlgorithm.SHA1.value,
-                                SignatureAlgorithm.ECDSA.value, 0);
-                        break;
-                    default:
-                        // no peer supported signature algorithms
-                }
-
-                if (algorithm == null) {
-                    supportedSignAlgs =
-                        Collections.<SignatureAndHashAlgorithm>emptySet();
-                } else {
-                    supportedSignAlgs =
-                        new ArrayList<SignatureAndHashAlgorithm>(1);
-                    supportedSignAlgs.add(algorithm);
-                }
-
-                // Sets the peer supported signature algorithm to use in KM
-                // temporarily.
-                session.setPeerSupportedSignatureAlgorithms(supportedSignAlgs);
-            }
-        }
-
-        switch (keyExchange) {
-        case K_RSA:
-            // need RSA certs for authentication
-            if (setupPrivateKeyAndChain("RSA") == false) {
-                return false;
-            }
-            break;
-        case K_RSA_EXPORT:
-            // need RSA certs for authentication
-            if (setupPrivateKeyAndChain("RSA") == false) {
-                return false;
-            }
-
-            try {
-               if (JsseJce.getRSAKeyLength(certs[0].getPublicKey()) > 512) {
-                    if (!setupEphemeralRSAKeys(suite.exportable)) {
-                        return false;
-                    }
-               }
-            } catch (RuntimeException e) {
-                // could not determine keylength, ignore key
-                return false;
-            }
-            break;
-        case K_DHE_RSA:
-            // need RSA certs for authentication
-            if (setupPrivateKeyAndChain("RSA") == false) {
-                return false;
-            }
-
-            // get preferable peer signature algorithm for server key exchange
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                preferableSignatureAlgorithm =
-                    SignatureAndHashAlgorithm.getPreferableAlgorithm(
-                                        supportedSignAlgs, "RSA", privateKey);
-                if (preferableSignatureAlgorithm == null) {
-                    return false;
-                }
-            }
-
-            setupEphemeralDHKeys(suite.exportable);
-            break;
-        case K_ECDHE_RSA:
-            // need RSA certs for authentication
-            if (setupPrivateKeyAndChain("RSA") == false) {
-                return false;
-            }
-
-            // get preferable peer signature algorithm for server key exchange
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                preferableSignatureAlgorithm =
-                    SignatureAndHashAlgorithm.getPreferableAlgorithm(
-                                        supportedSignAlgs, "RSA", privateKey);
-                if (preferableSignatureAlgorithm == null) {
-                    return false;
-                }
-            }
-
-            if (setupEphemeralECDHKeys() == false) {
-                return false;
-            }
-            break;
-        case K_DHE_DSS:
-            // get preferable peer signature algorithm for server key exchange
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                preferableSignatureAlgorithm =
-                    SignatureAndHashAlgorithm.getPreferableAlgorithm(
-                                                supportedSignAlgs, "DSA");
-                if (preferableSignatureAlgorithm == null) {
-                    return false;
-                }
-            }
-
-            // need DSS certs for authentication
-            if (setupPrivateKeyAndChain("DSA") == false) {
-                return false;
-            }
-            setupEphemeralDHKeys(suite.exportable);
-            break;
-        case K_ECDHE_ECDSA:
-            // get preferable peer signature algorithm for server key exchange
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                preferableSignatureAlgorithm =
-                    SignatureAndHashAlgorithm.getPreferableAlgorithm(
-                                            supportedSignAlgs, "ECDSA");
-                if (preferableSignatureAlgorithm == null) {
-                    return false;
-                }
-            }
-
-            // need EC cert signed using EC
-            if (setupPrivateKeyAndChain("EC_EC") == false) {
-                return false;
-            }
-            if (setupEphemeralECDHKeys() == false) {
-                return false;
-            }
-            break;
-        case K_ECDH_RSA:
-            // need EC cert signed using RSA
-            if (setupPrivateKeyAndChain("EC_RSA") == false) {
-                return false;
-            }
-            setupStaticECDHKeys();
-            break;
-        case K_ECDH_ECDSA:
-            // need EC cert signed using EC
-            if (setupPrivateKeyAndChain("EC_EC") == false) {
-                return false;
-            }
-            setupStaticECDHKeys();
-            break;
-        case K_KRB5:
-        case K_KRB5_EXPORT:
-            // need Kerberos Key
-            if (!setupKerberosKeys()) {
-                return false;
-            }
-            break;
-        case K_DH_ANON:
-            // no certs needed for anonymous
-            setupEphemeralDHKeys(suite.exportable);
-            break;
-        case K_ECDH_ANON:
-            // no certs needed for anonymous
-            if (setupEphemeralECDHKeys() == false) {
-                return false;
-            }
-            break;
-        default:
-            // internal error, unknown key exchange
-            throw new RuntimeException("Unrecognized cipherSuite: " + suite);
-        }
-        setCipherSuite(suite);
-
-        // set the peer implicit supported signature algorithms
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            if (peerSupportedSignAlgs == null) {
-                setPeerSupportedSignAlgs(supportedSignAlgs);
-                // we had alreay update the session
-            }
-        }
-        return true;
-    }
-
-    /*
-     * Get some "ephemeral" RSA keys for this context. This means
-     * generating them if it's not already been done.
-     *
-     * Note that we currently do not implement any ciphersuites that use
-     * strong ephemeral RSA. (We do not support the EXPORT1024 ciphersuites
-     * and standard RSA ciphersuites prohibit ephemeral mode for some reason)
-     * This means that export is always true and 512 bit keys are generated.
-     */
-    private boolean setupEphemeralRSAKeys(boolean export) {
-        KeyPair kp = sslContext.getEphemeralKeyManager().
-                        getRSAKeyPair(export, sslContext.getSecureRandom());
-        if (kp == null) {
-            return false;
-        } else {
-            tempPublicKey = kp.getPublic();
-            tempPrivateKey = kp.getPrivate();
-            return true;
-        }
-    }
-
-    /*
-     * Acquire some "ephemeral" Diffie-Hellman  keys for this handshake.
-     * We don't reuse these, for improved forward secrecy.
-     */
-    private void setupEphemeralDHKeys(boolean export) {
-        /*
-         * Diffie-Hellman keys ... we use 768 bit private keys due
-         * to the "use twice as many key bits as bits you want secret"
-         * rule of thumb, assuming we want the same size premaster
-         * secret with Diffie-Hellman and RSA key exchanges.  Except
-         * that exportable ciphers max out at 512 bits modulus values.
-         */
-        dh = new DHCrypt((export ? 512 : 768), sslContext.getSecureRandom());
-    }
-
-    // Setup the ephemeral ECDH parameters.
-    // If we cannot continue because we do not support any of the curves that
-    // the client requested, return false. Otherwise (all is well), return true.
-    private boolean setupEphemeralECDHKeys() {
-        int index = -1;
-        if (supportedCurves != null) {
-            // if the client sent the supported curves extension, pick the
-            // first one that we support;
-            for (int curveId : supportedCurves.curveIds()) {
-                if (SupportedEllipticCurvesExtension.isSupported(curveId)) {
-                    index = curveId;
-                    break;
-                }
-            }
-            if (index < 0) {
-                // no match found, cannot use this ciphersuite
-                return false;
-            }
-        } else {
-            // pick our preference
-            index = SupportedEllipticCurvesExtension.DEFAULT.curveIds()[0];
-        }
-        String oid = SupportedEllipticCurvesExtension.getCurveOid(index);
-        ecdh = new ECDHCrypt(oid, sslContext.getSecureRandom());
-        return true;
-    }
-
-    private void setupStaticECDHKeys() {
-        // don't need to check whether the curve is supported, already done
-        // in setupPrivateKeyAndChain().
-        ecdh = new ECDHCrypt(privateKey, certs[0].getPublicKey());
-    }
-
-    /**
-     * Retrieve the server key and certificate for the specified algorithm
-     * from the KeyManager and set the instance variables.
-     *
-     * @return true if successful, false if not available or invalid
-     */
-    private boolean setupPrivateKeyAndChain(String algorithm) {
-        X509ExtendedKeyManager km = sslContext.getX509KeyManager();
-        String alias;
-        if (conn != null) {
-            alias = km.chooseServerAlias(algorithm, null, conn);
-        } else {
-            alias = km.chooseEngineServerAlias(algorithm, null, engine);
-        }
-        if (alias == null) {
-            return false;
-        }
-        PrivateKey tempPrivateKey = km.getPrivateKey(alias);
-        if (tempPrivateKey == null) {
-            return false;
-        }
-        X509Certificate[] tempCerts = km.getCertificateChain(alias);
-        if ((tempCerts == null) || (tempCerts.length == 0)) {
-            return false;
-        }
-        String keyAlgorithm = algorithm.split("_")[0];
-        PublicKey publicKey = tempCerts[0].getPublicKey();
-        if ((tempPrivateKey.getAlgorithm().equals(keyAlgorithm) == false)
-                || (publicKey.getAlgorithm().equals(keyAlgorithm) == false)) {
-            return false;
-        }
-        // For ECC certs, check whether we support the EC domain parameters.
-        // If the client sent a SupportedEllipticCurves ClientHello extension,
-        // check against that too.
-        if (keyAlgorithm.equals("EC")) {
-            if (publicKey instanceof ECPublicKey == false) {
-                return false;
-            }
-            ECParameterSpec params = ((ECPublicKey)publicKey).getParams();
-            int index = SupportedEllipticCurvesExtension.getCurveIndex(params);
-            if (SupportedEllipticCurvesExtension.isSupported(index) == false) {
-                return false;
-            }
-            if ((supportedCurves != null) && !supportedCurves.contains(index)) {
-                return false;
-            }
-        }
-        this.privateKey = tempPrivateKey;
-        this.certs = tempCerts;
-        return true;
-    }
-
-    /**
-     * Retrieve the Kerberos key for the specified server principal
-     * from the JAAS configuration file.
-     *
-     * @return true if successful, false if not available or invalid
-     */
-    private boolean setupKerberosKeys() {
-        if (kerberosKeys != null) {
-            return true;
-        }
-        try {
-            final AccessControlContext acc = getAccSE();
-            kerberosKeys = AccessController.doPrivileged(
-                // Eliminate dependency on KerberosKey
-                new PrivilegedExceptionAction<SecretKey[]>() {
-                public SecretKey[] run() throws Exception {
-                    // get kerberos key for the default principal
-                    return Krb5Helper.getServerKeys(acc);
-                        }});
-
-            // check permission to access and use the secret key of the
-            // Kerberized "host" service
-            if (kerberosKeys != null && kerberosKeys.length > 0) {
-                if (debug != null && Debug.isOn("handshake")) {
-                    for (SecretKey k: kerberosKeys) {
-                        System.out.println("Using Kerberos key: " +
-                            k);
-                    }
-                }
-
-                String serverPrincipal =
-                    Krb5Helper.getServerPrincipalName(kerberosKeys[0]);
-                SecurityManager sm = System.getSecurityManager();
-                try {
-                   if (sm != null) {
-                      // Eliminate dependency on ServicePermission
-                      sm.checkPermission(Krb5Helper.getServicePermission(
-                          serverPrincipal, "accept"), acc);
-                   }
-                } catch (SecurityException se) {
-                   kerberosKeys = null;
-                   // %%% destroy keys? or will that affect Subject?
-                   if (debug != null && Debug.isOn("handshake"))
-                      System.out.println("Permission to access Kerberos"
-                                + " secret key denied");
-                   return false;
-                }
-            }
-            return (kerberosKeys != null && kerberosKeys.length > 0);
-        } catch (PrivilegedActionException e) {
-            // Likely exception here is LoginExceptin
-            if (debug != null && Debug.isOn("handshake")) {
-                System.out.println("Attempt to obtain Kerberos key failed: "
-                                + e.toString());
-            }
-            return false;
-        }
-    }
-
-    /*
-     * For Kerberos ciphers, the premaster secret is encrypted using
-     * the session key. See RFC 2712.
-     */
-    private SecretKey clientKeyExchange(KerberosClientKeyExchange mesg)
-        throws IOException {
-
-        if (debug != null && Debug.isOn("handshake")) {
-            mesg.print(System.out);
-        }
-
-        // Record the principals involved in exchange
-        session.setPeerPrincipal(mesg.getPeerPrincipal());
-        session.setLocalPrincipal(mesg.getLocalPrincipal());
-
-        byte[] b = mesg.getUnencryptedPreMasterSecret();
-        return new SecretKeySpec(b, "TlsPremasterSecret");
-    }
-
-    /*
-     * Diffie Hellman key exchange is used when the server presented
-     * D-H parameters in its certificate (signed using RSA or DSS/DSA),
-     * or else the server presented no certificate but sent D-H params
-     * in a ServerKeyExchange message.  Use of D-H is specified by the
-     * cipher suite chosen.
-     *
-     * The message optionally contains the client's D-H public key (if
-     * it wasn't not sent in a client certificate).  As always with D-H,
-     * if a client and a server have each other's D-H public keys and
-     * they use common algorithm parameters, they have a shared key
-     * that's derived via the D-H calculation.  That key becomes the
-     * pre-master secret.
-     */
-    private SecretKey clientKeyExchange(DHClientKeyExchange mesg)
-            throws IOException {
-
-        if (debug != null && Debug.isOn("handshake")) {
-            mesg.print(System.out);
-        }
-        return dh.getAgreedSecret(mesg.getClientPublicKey(), false);
-    }
-
-    private SecretKey clientKeyExchange(ECDHClientKeyExchange mesg)
-            throws IOException {
-
-        if (debug != null && Debug.isOn("handshake")) {
-            mesg.print(System.out);
-        }
-        return ecdh.getAgreedSecret(mesg.getEncodedPoint());
-    }
-
-    /*
-     * Client wrote a message to verify the certificate it sent earlier.
-     *
-     * Note that this certificate isn't involved in key exchange.  Client
-     * authentication messages are included in the checksums used to
-     * validate the handshake (e.g. Finished messages).  Other than that,
-     * the _exact_ identity of the client is less fundamental to protocol
-     * security than its role in selecting keys via the pre-master secret.
-     */
-    private void clientCertificateVerify(CertificateVerify mesg)
-            throws IOException {
-
-        if (debug != null && Debug.isOn("handshake")) {
-            mesg.print(System.out);
-        }
-
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            SignatureAndHashAlgorithm signAlg =
-                mesg.getPreferableSignatureAlgorithm();
-            if (signAlg == null) {
-                throw new SSLHandshakeException(
-                        "Illegal CertificateVerify message");
-            }
-
-            String hashAlg =
-                SignatureAndHashAlgorithm.getHashAlgorithmName(signAlg);
-            if (hashAlg == null || hashAlg.length() == 0) {
-                throw new SSLHandshakeException(
-                        "No supported hash algorithm");
-            }
-
-            handshakeHash.setCertificateVerifyAlg(hashAlg);
-        }
-
-        try {
-            PublicKey publicKey =
-                session.getPeerCertificates()[0].getPublicKey();
-
-            boolean valid = mesg.verify(protocolVersion, handshakeHash,
-                                        publicKey, session.getMasterSecret());
-            if (valid == false) {
-                fatalSE(Alerts.alert_bad_certificate,
-                            "certificate verify message signature error");
-            }
-        } catch (GeneralSecurityException e) {
-            fatalSE(Alerts.alert_bad_certificate,
-                "certificate verify format error", e);
-        }
-
-        // reset the flag for clientCertificateVerify message
-        needClientVerify = false;
-    }
-
-
-    /*
-     * Client writes "finished" at the end of its handshake, after cipher
-     * spec is changed.   We verify it and then send ours.
-     *
-     * When we're resuming a session, we'll have already sent our own
-     * Finished message so just the verification is needed.
-     */
-    private void clientFinished(Finished mesg) throws IOException {
-        if (debug != null && Debug.isOn("handshake")) {
-            mesg.print(System.out);
-        }
-
-        /*
-         * Verify if client did send the certificate when client
-         * authentication was required, otherwise server should not proceed
-         */
-        if (doClientAuth == SSLEngineImpl.clauth_required) {
-           // get X500Principal of the end-entity certificate for X509-based
-           // ciphersuites, or Kerberos principal for Kerberos ciphersuites
-           session.getPeerPrincipal();
-        }
-
-        /*
-         * Verify if client did send clientCertificateVerify message following
-         * the client Certificate, otherwise server should not proceed
-         */
-        if (needClientVerify) {
-                fatalSE(Alerts.alert_handshake_failure,
-                        "client did not send certificate verify message");
-        }
-
-        /*
-         * Verify the client's message with the "before" digest of messages,
-         * and forget about continuing to use that digest.
-         */
-        boolean verified = mesg.verify(handshakeHash, Finished.CLIENT,
-            session.getMasterSecret());
-
-        if (!verified) {
-            fatalSE(Alerts.alert_handshake_failure,
-                        "client 'finished' message doesn't verify");
-            // NOTREACHED
-        }
-
-        /*
-         * save client verify data for secure renegotiation
-         */
-        if (secureRenegotiation) {
-            clientVerifyData = mesg.getVerifyData();
-        }
-
-        /*
-         * OK, it verified.  If we're doing the full handshake, add that
-         * "Finished" message to the hash of handshake messages, then send
-         * the change_cipher_spec and Finished message.
-         */
-        if (!resumingSession) {
-            input.digestNow();
-            sendChangeCipherAndFinish(true);
-        }
-
-        /*
-         * Update the session cache only after the handshake completed, else
-         * we're open to an attack against a partially completed handshake.
-         */
-        session.setLastAccessedTime(System.currentTimeMillis());
-        if (!resumingSession && session.isRejoinable()) {
-            ((SSLSessionContextImpl)sslContext.engineGetServerSessionContext())
-                .put(session);
-            if (debug != null && Debug.isOn("session")) {
-                System.out.println(
-                    "%% Cached server session: " + session);
-            }
-        } else if (!resumingSession &&
-                debug != null && Debug.isOn("session")) {
-            System.out.println(
-                "%% Didn't cache non-resumable server session: "
-                + session);
-        }
-    }
-
-    /*
-     * Compute finished message with the "server" digest (and then forget
-     * about that digest, it can't be used again).
-     */
-    private void sendChangeCipherAndFinish(boolean finishedTag)
-            throws IOException {
-
-        output.flush();
-
-        Finished mesg = new Finished(protocolVersion, handshakeHash,
-            Finished.SERVER, session.getMasterSecret(), cipherSuite);
-
-        /*
-         * Send the change_cipher_spec record; then our Finished handshake
-         * message will be the last handshake message.  Flush, and now we
-         * are ready for application data!!
-         */
-        sendChangeCipherSpec(mesg, finishedTag);
-
-        /*
-         * save server verify data for secure renegotiation
-         */
-        if (secureRenegotiation) {
-            serverVerifyData = mesg.getVerifyData();
-        }
-
-        /*
-         * Update state machine so client MUST send 'finished' next
-         * The update should only take place if it is not in the fast
-         * handshake mode since the server has to wait for a finished
-         * message from the client.
-         */
-        if (finishedTag) {
-            state = HandshakeMessage.ht_finished;
-        }
-    }
-
-
-    /*
-     * Returns a HelloRequest message to kickstart renegotiations
-     */
-    HandshakeMessage getKickstartMessage() {
-        return new HelloRequest();
-    }
-
-
-    /*
-     * Fault detected during handshake.
-     */
-    void handshakeAlert(byte description) throws SSLProtocolException {
-
-        String message = Alerts.alertDescription(description);
-
-        if (debug != null && Debug.isOn("handshake")) {
-            System.out.println("SSL -- handshake alert:  "
-                + message);
-        }
-
-        /*
-         * It's ok to get a no_certificate alert from a client of which
-         * we *requested* authentication information.
-         * However, if we *required* it, then this is not acceptable.
-         *
-         * Anyone calling getPeerCertificates() on the
-         * session will get an SSLPeerUnverifiedException.
-         */
-        if ((description == Alerts.alert_no_certificate) &&
-                (doClientAuth == SSLEngineImpl.clauth_requested)) {
-            return;
-        }
-
-        throw new SSLProtocolException("handshake alert: " + message);
-    }
-
-    /*
-     * RSA key exchange is normally used.  The client encrypts a "pre-master
-     * secret" with the server's public key, from the Certificate (or else
-     * ServerKeyExchange) message that was sent to it by the server.  That's
-     * decrypted using the private key before we get here.
-     */
-    private SecretKey clientKeyExchange(RSAClientKeyExchange mesg)
-            throws IOException {
-
-        if (debug != null && Debug.isOn("handshake")) {
-            mesg.print(System.out);
-        }
-        return mesg.preMaster;
-    }
-
-    /*
-     * Verify the certificate sent by the client. We'll only get one if we
-     * sent a CertificateRequest to request client authentication. If we
-     * are in TLS mode, the client may send a message with no certificates
-     * to indicate it does not have an appropriate chain. (In SSLv3 mode,
-     * it would send a no certificate alert).
-     */
-    private void clientCertificate(CertificateMsg mesg) throws IOException {
-        if (debug != null && Debug.isOn("handshake")) {
-            mesg.print(System.out);
-        }
-
-        X509Certificate[] peerCerts = mesg.getCertificateChain();
-
-        if (peerCerts.length == 0) {
-            /*
-             * If the client authentication is only *REQUESTED* (e.g.
-             * not *REQUIRED*, this is an acceptable condition.)
-             */
-            if (doClientAuth == SSLEngineImpl.clauth_requested) {
-                // Smart (aka stupid) to forecast that no CertificateVerify
-                // message will be received.
-                if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                    handshakeHash.setCertificateVerifyAlg(null);
-                }
-                return;
-            } else {
-                fatalSE(Alerts.alert_bad_certificate,
-                    "null cert chain");
-            }
-        }
-
-        // ask the trust manager to verify the chain
-        X509TrustManager tm = sslContext.getX509TrustManager();
-
-        try {
-            // find out the types of client authentication used
-            PublicKey key = peerCerts[0].getPublicKey();
-            String keyAlgorithm = key.getAlgorithm();
-            String authType;
-            if (keyAlgorithm.equals("RSA")) {
-                authType = "RSA";
-            } else if (keyAlgorithm.equals("DSA")) {
-                authType = "DSA";
-            } else if (keyAlgorithm.equals("EC")) {
-                authType = "EC";
-            } else {
-                // unknown public key type
-                authType = "UNKNOWN";
-            }
-
-            if (tm instanceof X509ExtendedTrustManager) {
-                if (conn != null) {
-                    ((X509ExtendedTrustManager)tm).checkClientTrusted(
-                        peerCerts.clone(),
-                        authType,
-                        conn);
-                } else {
-                    ((X509ExtendedTrustManager)tm).checkClientTrusted(
-                        peerCerts.clone(),
-                        authType,
-                        engine);
-                }
-            } else {
-                // Unlikely to happen, because we have wrapped the old
-                // X509TrustManager with the new X509ExtendedTrustManager.
-                throw new CertificateException(
-                    "Improper X509TrustManager implementation");
-            }
-        } catch (CertificateException e) {
-            // This will throw an exception, so include the original error.
-            fatalSE(Alerts.alert_certificate_unknown, e);
-        }
-        // set the flag for clientCertificateVerify message
-        needClientVerify = true;
-
-        session.setPeerCertificates(peerCerts);
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/SessionId.java b/ojluni/src/main/java/sun/security/ssl/SessionId.java
deleted file mode 100755
index 1707d42..0000000
--- a/ojluni/src/main/java/sun/security/ssl/SessionId.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.security.SecureRandom;
-
-/**
- * Encapsulates an SSL session ID.  SSL Session IDs are not reused by
- * servers during the lifetime of any sessions it created.  Sessions may
- * be used by many connections, either concurrently (for example, two
- * connections to a web server at the same time) or sequentially (over as
- * long a time period as is allowed by a given server).
- *
- * @author Satish Dharmaraj
- * @author David Brownell
- */
-final
-class SessionId
-{
-    private byte sessionId [];          // max 32 bytes
-
-    /** Constructs a new session ID ... perhaps for a rejoinable session */
-    SessionId (boolean isRejoinable, SecureRandom generator)
-    {
-        if (isRejoinable)
-            // this will be unique, it's a timestamp plus much randomness
-            sessionId = new RandomCookie (generator).random_bytes;
-        else
-            sessionId = new byte [0];
-    }
-
-    /** Constructs a session ID from a byte array (max size 32 bytes) */
-    SessionId (byte sessionId [])
-        { this.sessionId = sessionId; }
-
-    /** Returns the length of the ID, in bytes */
-    int length ()
-        { return sessionId.length; }
-
-    /** Returns the bytes in the ID.  May be an empty array.  */
-    byte [] getId ()
-    {
-        return sessionId.clone ();
-    }
-
-    /** Returns the ID as a string */
-    public String toString ()
-    {
-        int             len = sessionId.length;
-        StringBuffer    s = new StringBuffer (10 + 2 * len);
-
-        s.append ("{");
-        for (int i = 0; i < len; i++) {
-            s.append (0x0ff & sessionId [i]);
-            if (i != (len - 1))
-                s.append (", ");
-        }
-        s.append ("}");
-        return s.toString ();
-    }
-
-
-    /** Returns a value which is the same for session IDs which are equal */
-    public int hashCode ()
-    {
-        int     retval = 0;
-
-        for (int i = 0; i < sessionId.length; i++)
-            retval += sessionId [i];
-        return retval;
-    }
-
-    /** Returns true if the parameter is the same session ID */
-    public boolean equals (Object obj)
-    {
-        if (!(obj instanceof SessionId))
-            return false;
-
-        SessionId s = (SessionId) obj;
-        byte b [] = s.getId ();
-
-        if (b.length != sessionId.length)
-            return false;
-        for (int i = 0; i < sessionId.length; i++) {
-            if (b [i] != sessionId [i])
-                return false;
-        }
-        return true;
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/SignatureAndHashAlgorithm.java b/ojluni/src/main/java/sun/security/ssl/SignatureAndHashAlgorithm.java
deleted file mode 100755
index 043b9b1..0000000
--- a/ojluni/src/main/java/sun/security/ssl/SignatureAndHashAlgorithm.java
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.security.AlgorithmConstraints;
-import java.security.CryptoPrimitive;
-import java.security.PrivateKey;
-
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.EnumSet;
-import java.util.TreeMap;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.ArrayList;
-
-import sun.security.util.KeyUtil;
-
-/**
- * Signature and hash algorithm.
- *
- * [RFC5246] The client uses the "signature_algorithms" extension to
- * indicate to the server which signature/hash algorithm pairs may be
- * used in digital signatures.  The "extension_data" field of this
- * extension contains a "supported_signature_algorithms" value.
- *
- *     enum {
- *         none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
- *         sha512(6), (255)
- *     } HashAlgorithm;
- *
- *     enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
- *       SignatureAlgorithm;
- *
- *     struct {
- *           HashAlgorithm hash;
- *           SignatureAlgorithm signature;
- *     } SignatureAndHashAlgorithm;
- */
-final class SignatureAndHashAlgorithm {
-
-    // minimum priority for default enabled algorithms
-    final static int SUPPORTED_ALG_PRIORITY_MAX_NUM = 0x00F0;
-
-    // performance optimization
-    private final static Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
-                                    EnumSet.of(CryptoPrimitive.SIGNATURE);
-
-    // supported pairs of signature and hash algorithm
-    private final static Map<Integer, SignatureAndHashAlgorithm> supportedMap;
-    private final static Map<Integer, SignatureAndHashAlgorithm> priorityMap;
-
-    // the hash algorithm
-    private HashAlgorithm hash;
-
-    // the signature algorithm
-    private SignatureAlgorithm signature;
-
-    // id in 16 bit MSB format, i.e. 0x0603 for SHA512withECDSA
-    private int id;
-
-    // the standard algorithm name, for example "SHA512withECDSA"
-    private String algorithm;
-
-    // Priority for the preference order. The lower the better.
-    //
-    // If the algorithm is unsupported, its priority should be bigger
-    // than SUPPORTED_ALG_PRIORITY_MAX_NUM.
-    private int priority;
-
-    // constructor for supported algorithm
-    private SignatureAndHashAlgorithm(HashAlgorithm hash,
-            SignatureAlgorithm signature, String algorithm, int priority) {
-        this.hash = hash;
-        this.signature = signature;
-        this.algorithm = algorithm;
-        this.id = ((hash.value & 0xFF) << 8) | (signature.value & 0xFF);
-        this.priority = priority;
-    }
-
-    // constructor for unsupported algorithm
-    private SignatureAndHashAlgorithm(String algorithm, int id, int sequence) {
-        this.hash = HashAlgorithm.valueOf((id >> 8) & 0xFF);
-        this.signature = SignatureAlgorithm.valueOf(id & 0xFF);
-        this.algorithm = algorithm;
-        this.id = id;
-
-        // add one more to the sequece number, in case that the number is zero
-        this.priority = SUPPORTED_ALG_PRIORITY_MAX_NUM + sequence + 1;
-    }
-
-    // Note that we do not use the sequence argument for supported algorithms,
-    // so please don't sort by comparing the objects read from handshake
-    // messages.
-    static SignatureAndHashAlgorithm valueOf(int hash,
-            int signature, int sequence) {
-        hash &= 0xFF;
-        signature &= 0xFF;
-
-        int id = (hash << 8) | signature;
-        SignatureAndHashAlgorithm signAlg = supportedMap.get(id);
-        if (signAlg == null) {
-            // unsupported algorithm
-            signAlg = new SignatureAndHashAlgorithm(
-                "Unknown (hash:0x" + Integer.toString(hash, 16) +
-                ", signature:0x" + Integer.toString(signature, 16) + ")",
-                id, sequence);
-        }
-
-        return signAlg;
-    }
-
-    int getHashValue() {
-        return (id >> 8) & 0xFF;
-    }
-
-    int getSignatureValue() {
-        return id & 0xFF;
-    }
-
-    String getAlgorithmName() {
-        return algorithm;
-    }
-
-    // return the size of a SignatureAndHashAlgorithm structure in TLS record
-    static int sizeInRecord() {
-        return 2;
-    }
-
-    // Get local supported algorithm collection complying to
-    // algorithm constraints
-    static Collection<SignatureAndHashAlgorithm>
-            getSupportedAlgorithms(AlgorithmConstraints constraints) {
-
-        Collection<SignatureAndHashAlgorithm> supported = new ArrayList<>();
-        synchronized (priorityMap) {
-            for (SignatureAndHashAlgorithm sigAlg : priorityMap.values()) {
-                if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM &&
-                        constraints.permits(SIGNATURE_PRIMITIVE_SET,
-                                sigAlg.algorithm, null)) {
-                    supported.add(sigAlg);
-                }
-            }
-        }
-
-        return supported;
-    }
-
-    // Get supported algorithm collection from an untrusted collection
-    static Collection<SignatureAndHashAlgorithm> getSupportedAlgorithms(
-            Collection<SignatureAndHashAlgorithm> algorithms ) {
-        Collection<SignatureAndHashAlgorithm> supported = new ArrayList<>();
-        for (SignatureAndHashAlgorithm sigAlg : algorithms) {
-            if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM) {
-                supported.add(sigAlg);
-            }
-        }
-
-        return supported;
-    }
-
-    static String[] getAlgorithmNames(
-            Collection<SignatureAndHashAlgorithm> algorithms) {
-        ArrayList<String> algorithmNames = new ArrayList<>();
-        if (algorithms != null) {
-            for (SignatureAndHashAlgorithm sigAlg : algorithms) {
-                algorithmNames.add(sigAlg.algorithm);
-            }
-        }
-
-        String[] array = new String[algorithmNames.size()];
-        return algorithmNames.toArray(array);
-    }
-
-    static Set<String> getHashAlgorithmNames(
-            Collection<SignatureAndHashAlgorithm> algorithms) {
-        Set<String> algorithmNames = new HashSet<>();
-        if (algorithms != null) {
-            for (SignatureAndHashAlgorithm sigAlg : algorithms) {
-                if (sigAlg.hash.value > 0) {
-                    algorithmNames.add(sigAlg.hash.standardName);
-                }
-            }
-        }
-
-        return algorithmNames;
-    }
-
-    static String getHashAlgorithmName(SignatureAndHashAlgorithm algorithm) {
-        return algorithm.hash.standardName;
-    }
-
-    private static void supports(HashAlgorithm hash,
-            SignatureAlgorithm signature, String algorithm, int priority) {
-
-        SignatureAndHashAlgorithm pair =
-            new SignatureAndHashAlgorithm(hash, signature, algorithm, priority);
-        if (supportedMap.put(pair.id, pair) != null) {
-            throw new RuntimeException(
-                "Duplicate SignatureAndHashAlgorithm definition, id: " +
-                pair.id);
-        }
-        if (priorityMap.put(pair.priority, pair) != null) {
-            throw new RuntimeException(
-                "Duplicate SignatureAndHashAlgorithm definition, priority: " +
-                pair.priority);
-        }
-    }
-
-    static SignatureAndHashAlgorithm getPreferableAlgorithm(
-        Collection<SignatureAndHashAlgorithm> algorithms, String expected) {
-
-        return SignatureAndHashAlgorithm.getPreferableAlgorithm(
-                algorithms, expected, null);
-    }
-
-    static SignatureAndHashAlgorithm getPreferableAlgorithm(
-        Collection<SignatureAndHashAlgorithm> algorithms,
-        String expected, PrivateKey signingKey) {
-
-        if (expected == null && !algorithms.isEmpty()) {
-            for (SignatureAndHashAlgorithm sigAlg : algorithms) {
-                if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM) {
-                    return sigAlg;
-                }
-            }
-
-            return null;  // no supported algorithm
-        }
-
-        if (expected == null ) {
-            return null;  // no expected algorithm, no supported algorithm
-        }
-
-        /*
-         * Need to check RSA key length to match the length of hash value
-         */
-        int maxDigestLength = Integer.MAX_VALUE;
-        if (signingKey != null &&
-                "rsa".equalsIgnoreCase(signingKey.getAlgorithm()) &&
-                expected.equalsIgnoreCase("rsa")) {
-            /*
-             * RSA keys of 512 bits have been shown to be practically
-             * breakable, it does not make much sense to use the strong
-             * hash algorithm for keys whose key size less than 512 bits.
-             * So it is not necessary to caculate the required max digest
-             * length exactly.
-             *
-             * If key size is greater than or equals to 768, there is no max
-             * digest length limitation in currect implementation.
-             *
-             * If key size is greater than or equals to 512, but less than
-             * 768, the digest length should be less than or equal to 32 bytes.
-             *
-             * If key size is less than 512, the  digest length should be
-             * less than or equal to 20 bytes.
-             */
-            int keySize = KeyUtil.getKeySize(signingKey);
-            if (keySize >= 768) {
-                maxDigestLength = HashAlgorithm.SHA512.length;
-            } else if ((keySize >= 512) && (keySize < 768)) {
-                maxDigestLength = HashAlgorithm.SHA256.length;
-            } else if ((keySize > 0) && (keySize < 512)) {
-                maxDigestLength = HashAlgorithm.SHA1.length;
-            }   // Otherwise, cannot determine the key size, prefer the most
-                // perferable hash algorithm.
-        }
-
-        for (SignatureAndHashAlgorithm algorithm : algorithms) {
-            int signValue = algorithm.id & 0xFF;
-            if (expected.equalsIgnoreCase("rsa") &&
-                    signValue == SignatureAlgorithm.RSA.value) {
-                if (algorithm.hash.length <= maxDigestLength) {
-                    return algorithm;
-                }
-            } else if (
-                    (expected.equalsIgnoreCase("dsa") &&
-                        signValue == SignatureAlgorithm.DSA.value) ||
-                    (expected.equalsIgnoreCase("ecdsa") &&
-                        signValue == SignatureAlgorithm.ECDSA.value) ||
-                    (expected.equalsIgnoreCase("ec") &&
-                        signValue == SignatureAlgorithm.ECDSA.value)) {
-                return algorithm;
-            }
-        }
-
-        return null;
-    }
-
-    static enum HashAlgorithm {
-        UNDEFINED("undefined",        "", -1, -1),
-        NONE(          "none",    "NONE",  0, -1),
-        MD5(            "md5",     "MD5",  1, 16),
-        SHA1(          "sha1",   "SHA-1",  2, 20),
-        SHA224(      "sha224", "SHA-224",  3, 28),
-        SHA256(      "sha256", "SHA-256",  4, 32),
-        SHA384(      "sha384", "SHA-384",  5, 48),
-        SHA512(      "sha512", "SHA-512",  6, 64);
-
-        final String name;  // not the standard signature algorithm name
-                            // except the UNDEFINED, other names are defined
-                            // by TLS 1.2 protocol
-        final String standardName; // the standard MessageDigest algorithm name
-        final int value;
-        final int length;   // digest length in bytes, -1 means not applicable
-
-        private HashAlgorithm(String name, String standardName,
-                int value, int length) {
-            this.name = name;
-            this.standardName = standardName;
-            this.value = value;
-            this.length = length;
-        }
-
-        static HashAlgorithm valueOf(int value) {
-            HashAlgorithm algorithm = UNDEFINED;
-            switch (value) {
-                case 0:
-                    algorithm = NONE;
-                    break;
-                case 1:
-                    algorithm = MD5;
-                    break;
-                case 2:
-                    algorithm = SHA1;
-                    break;
-                case 3:
-                    algorithm = SHA224;
-                    break;
-                case 4:
-                    algorithm = SHA256;
-                    break;
-                case 5:
-                    algorithm = SHA384;
-                    break;
-                case 6:
-                    algorithm = SHA512;
-                    break;
-            }
-
-            return algorithm;
-        }
-    }
-
-    static enum SignatureAlgorithm {
-        UNDEFINED("undefined", -1),
-        ANONYMOUS("anonymous",  0),
-        RSA(            "rsa",  1),
-        DSA(            "dsa",  2),
-        ECDSA(        "ecdsa",  3);
-
-        final String name;  // not the standard signature algorithm name
-                            // except the UNDEFINED, other names are defined
-                            // by TLS 1.2 protocol
-        final int value;
-
-        private SignatureAlgorithm(String name, int value) {
-            this.name = name;
-            this.value = value;
-        }
-
-        static SignatureAlgorithm valueOf(int value) {
-            SignatureAlgorithm algorithm = UNDEFINED;
-            switch (value) {
-                case 0:
-                    algorithm = ANONYMOUS;
-                    break;
-                case 1:
-                    algorithm = RSA;
-                    break;
-                case 2:
-                    algorithm = DSA;
-                    break;
-                case 3:
-                    algorithm = ECDSA;
-                    break;
-            }
-
-            return algorithm;
-        }
-    }
-
-    static {
-        supportedMap = Collections.synchronizedSortedMap(
-            new TreeMap<Integer, SignatureAndHashAlgorithm>());
-        priorityMap = Collections.synchronizedSortedMap(
-            new TreeMap<Integer, SignatureAndHashAlgorithm>());
-
-        synchronized (supportedMap) {
-            int p = SUPPORTED_ALG_PRIORITY_MAX_NUM;
-            supports(HashAlgorithm.MD5,         SignatureAlgorithm.RSA,
-                    "MD5withRSA",           --p);
-            supports(HashAlgorithm.SHA1,        SignatureAlgorithm.DSA,
-                    "SHA1withDSA",          --p);
-            supports(HashAlgorithm.SHA1,        SignatureAlgorithm.RSA,
-                    "SHA1withRSA",          --p);
-            supports(HashAlgorithm.SHA1,        SignatureAlgorithm.ECDSA,
-                    "SHA1withECDSA",        --p);
-            supports(HashAlgorithm.SHA224,      SignatureAlgorithm.RSA,
-                    "SHA224withRSA",        --p);
-            supports(HashAlgorithm.SHA224,      SignatureAlgorithm.ECDSA,
-                    "SHA224withECDSA",      --p);
-            supports(HashAlgorithm.SHA256,      SignatureAlgorithm.RSA,
-                    "SHA256withRSA",        --p);
-            supports(HashAlgorithm.SHA256,      SignatureAlgorithm.ECDSA,
-                    "SHA256withECDSA",      --p);
-            supports(HashAlgorithm.SHA384,      SignatureAlgorithm.RSA,
-                    "SHA384withRSA",        --p);
-            supports(HashAlgorithm.SHA384,      SignatureAlgorithm.ECDSA,
-                    "SHA384withECDSA",      --p);
-            supports(HashAlgorithm.SHA512,      SignatureAlgorithm.RSA,
-                    "SHA512withRSA",        --p);
-            supports(HashAlgorithm.SHA512,      SignatureAlgorithm.ECDSA,
-                    "SHA512withECDSA",      --p);
-        }
-    }
-}
-
diff --git a/ojluni/src/main/java/sun/security/ssl/SunJSSE.java b/ojluni/src/main/java/sun/security/ssl/SunJSSE.java
deleted file mode 100755
index 16cb35c..0000000
--- a/ojluni/src/main/java/sun/security/ssl/SunJSSE.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.security.*;
-
-/**
- * The JSSE provider.
- *
- * The RSA implementation has been removed from JSSE, but we still need to
- * register the same algorithms for compatibility. We just point to the RSA
- * implementation in the SunRsaSign provider. This works because all classes
- * are in the bootclasspath and therefore loaded by the same classloader.
- *
- * SunJSSE now supports an experimental FIPS compliant mode when used with an
- * appropriate FIPS certified crypto provider. In FIPS mode, we:
- *  . allow only TLS 1.0 or later
- *  . allow only FIPS approved ciphersuites
- *  . perform all crypto in the FIPS crypto provider
- *
- * It is currently not possible to use both FIPS compliant SunJSSE and
- * standard JSSE at the same time because of the various static data structures
- * we use.
- *
- * However, we do want to allow FIPS mode to be enabled at runtime and without
- * editing the java.security file. That means we need to allow
- * Security.removeProvider("SunJSSE") to work, which creates an instance of
- * this class in non-FIPS mode. That is why we delay the selection of the mode
- * as long as possible. This is until we open an SSL/TLS connection and the
- * data structures need to be initialized or until SunJSSE is initialized in
- * FIPS mode.
- *
- */
-public abstract class SunJSSE extends java.security.Provider {
-
-    private static final long serialVersionUID = 3231825739635378733L;
-
-    private static String info = "Sun JSSE provider" +
-        "(PKCS12, SunX509 key/trust factories, SSLv3, TLSv1)";
-
-    private static String fipsInfo =
-        "Sun JSSE provider (FIPS mode, crypto provider ";
-
-    // tri-valued flag:
-    // null  := no final decision made
-    // false := data structures initialized in non-FIPS mode
-    // true  := data structures initialized in FIPS mode
-    private static Boolean fips;
-
-    // the FIPS certificate crypto provider that we use to perform all crypto
-    // operations. null in non-FIPS mode
-    static java.security.Provider cryptoProvider;
-
-    protected static synchronized boolean isFIPS() {
-        if (fips == null) {
-            fips = false;
-        }
-        return fips;
-    }
-
-    // ensure we can use FIPS mode using the specified crypto provider.
-    // enable FIPS mode if not already enabled.
-    private static synchronized void ensureFIPS(java.security.Provider p) {
-        if (fips == null) {
-            fips = true;
-            cryptoProvider = p;
-        } else {
-            if (fips == false) {
-                throw new ProviderException
-                    ("SunJSSE already initialized in non-FIPS mode");
-            }
-            if (cryptoProvider != p) {
-                throw new ProviderException
-                    ("SunJSSE already initialized with FIPS crypto provider "
-                    + cryptoProvider);
-            }
-        }
-    }
-
-    // standard constructor
-    protected SunJSSE() {
-        super("SunJSSE", 1.7d, info);
-        subclassCheck();
-        if (Boolean.TRUE.equals(fips)) {
-            throw new ProviderException
-                ("SunJSSE is already initialized in FIPS mode");
-        }
-        registerAlgorithms(false);
-    }
-
-    // prefered constructor to enable FIPS mode at runtime
-    protected SunJSSE(java.security.Provider cryptoProvider){
-        this(checkNull(cryptoProvider), cryptoProvider.getName());
-    }
-
-    // constructor to enable FIPS mode from java.security file
-    protected SunJSSE(String cryptoProvider){
-        this(null, checkNull(cryptoProvider));
-    }
-
-    private static <T> T checkNull(T t) {
-        if (t == null) {
-            throw new ProviderException("cryptoProvider must not be null");
-        }
-        return t;
-    }
-
-    private SunJSSE(java.security.Provider cryptoProvider,
-            String providerName) {
-        super("SunJSSE", 1.6d, fipsInfo + providerName + ")");
-        subclassCheck();
-        if (cryptoProvider == null) {
-            // Calling Security.getProvider() will cause other providers to be
-            // loaded. That is not good but unavoidable here.
-            cryptoProvider = Security.getProvider(providerName);
-            if (cryptoProvider == null) {
-                throw new ProviderException
-                    ("Crypto provider not installed: " + providerName);
-            }
-        }
-        ensureFIPS(cryptoProvider);
-        registerAlgorithms(true);
-    }
-
-    private void registerAlgorithms(final boolean isfips) {
-        AccessController.doPrivileged(new PrivilegedAction<Object>() {
-            public Object run() {
-                doRegister(isfips);
-                return null;
-            }
-        });
-    }
-
-    private void doRegister(boolean isfips) {
-        if (isfips == false) {
-            put("KeyFactory.RSA",
-                "sun.security.rsa.RSAKeyFactory");
-            put("Alg.Alias.KeyFactory.1.2.840.113549.1.1", "RSA");
-            put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1", "RSA");
-
-            put("KeyPairGenerator.RSA",
-                "sun.security.rsa.RSAKeyPairGenerator");
-            put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1", "RSA");
-            put("Alg.Alias.KeyPairGenerator.OID.1.2.840.113549.1.1", "RSA");
-
-            put("Signature.MD2withRSA",
-                "sun.security.rsa.RSASignature$MD2withRSA");
-            put("Alg.Alias.Signature.1.2.840.113549.1.1.2", "MD2withRSA");
-            put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.2",
-                "MD2withRSA");
-
-            put("Signature.MD5withRSA",
-                "sun.security.rsa.RSASignature$MD5withRSA");
-            put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA");
-            put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.4",
-                "MD5withRSA");
-
-            put("Signature.SHA1withRSA",
-                "sun.security.rsa.RSASignature$SHA1withRSA");
-            put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1withRSA");
-            put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5",
-                "SHA1withRSA");
-            put("Alg.Alias.Signature.1.3.14.3.2.29", "SHA1withRSA");
-            put("Alg.Alias.Signature.OID.1.3.14.3.2.29", "SHA1withRSA");
-
-        }
-        put("Signature.MD5andSHA1withRSA",
-            "sun.security.ssl.RSASignature");
-
-        put("KeyManagerFactory.SunX509",
-            "sun.security.ssl.KeyManagerFactoryImpl$SunX509");
-        put("KeyManagerFactory.NewSunX509",
-            "sun.security.ssl.KeyManagerFactoryImpl$X509");
-        put("Alg.Alias.KeyManagerFactory.PKIX", "NewSunX509");
-
-        put("TrustManagerFactory.SunX509",
-            "sun.security.ssl.TrustManagerFactoryImpl$SimpleFactory");
-        put("TrustManagerFactory.PKIX",
-            "sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory");
-        put("Alg.Alias.TrustManagerFactory.SunPKIX", "PKIX");
-        put("Alg.Alias.TrustManagerFactory.X509", "PKIX");
-        put("Alg.Alias.TrustManagerFactory.X.509", "PKIX");
-
-        put("SSLContext.TLSv1",
-            "sun.security.ssl.SSLContextImpl$TLS10Context");
-        put("Alg.Alias.SSLContext.TLS", "TLSv1");
-        if (isfips == false) {
-            put("Alg.Alias.SSLContext.SSL", "TLSv1");
-            put("Alg.Alias.SSLContext.SSLv3", "TLSv1");
-        }
-
-        put("SSLContext.TLSv1.1",
-            "sun.security.ssl.SSLContextImpl$TLS11Context");
-        put("SSLContext.TLSv1.2",
-            "sun.security.ssl.SSLContextImpl$TLS12Context");
-        put("SSLContext.Default",
-            "sun.security.ssl.SSLContextImpl$DefaultSSLContext");
-
-        /*
-         * KeyStore
-         */
-        put("KeyStore.PKCS12",
-            "sun.security.pkcs12.PKCS12KeyStore");
-    }
-
-    private void subclassCheck() {
-        if (getClass() != com.sun.net.ssl.internal.ssl.Provider.class) {
-            throw new AssertionError("Illegal subclass: " + getClass());
-        }
-    }
-
-    @Override
-    protected final void finalize() throws Throwable {
-        // empty
-        super.finalize();
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/SunX509KeyManagerImpl.java b/ojluni/src/main/java/sun/security/ssl/SunX509KeyManagerImpl.java
deleted file mode 100755
index bdf113d..0000000
--- a/ojluni/src/main/java/sun/security/ssl/SunX509KeyManagerImpl.java
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import javax.net.ssl.*;
-import java.security.*;
-import java.security.cert.*;
-import java.security.cert.Certificate;
-import java.util.*;
-import java.net.Socket;
-
-import javax.security.auth.x500.X500Principal;
-
-
-/**
- * An implemention of X509KeyManager backed by a KeyStore.
- *
- * The backing KeyStore is inspected when this object is constructed.
- * All key entries containing a PrivateKey and a non-empty chain of
- * X509Certificate are then copied into an internal store. This means
- * that subsequent modifications of the KeyStore have no effect on the
- * X509KeyManagerImpl object.
- *
- * Note that this class assumes that all keys are protected by the same
- * password.
- *
- * The JSSE handshake code currently calls into this class via
- * chooseClientAlias() and chooseServerAlias() to find the certificates to
- * use. As implemented here, both always return the first alias returned by
- * getClientAliases() and getServerAliases(). In turn, these methods are
- * implemented by calling getAliases(), which performs the actual lookup.
- *
- * Note that this class currently implements no checking of the local
- * certificates. In particular, it is *not* guaranteed that:
- *  . the certificates are within their validity period and not revoked
- *  . the signatures verify
- *  . they form a PKIX compliant chain.
- *  . the certificate extensions allow the certificate to be used for
- *    the desired purpose.
- *
- * Chains that fail any of these criteria will probably be rejected by
- * the remote peer.
- *
- */
-final class SunX509KeyManagerImpl extends X509ExtendedKeyManager {
-
-    private static final Debug debug = Debug.getInstance("ssl");
-
-    private static final String[] STRING0 = new String[0];
-
-    /*
-     * The credentials from the KeyStore as
-     * Map: String(alias) -> X509Credentials(credentials)
-     */
-    private Map<String,X509Credentials> credentialsMap;
-
-    /*
-     * Cached server aliases for the case issuers == null.
-     * (in the current JSSE implementation, issuers are always null for
-     * server certs). See chooseServerAlias() for details.
-     *
-     * Map: String(keyType) -> String[](alias)
-     */
-    private Map<String,String[]> serverAliasCache;
-
-    /*
-     * Basic container for credentials implemented as an inner class.
-     */
-    private static class X509Credentials {
-        PrivateKey privateKey;
-        X509Certificate[] certificates;
-        private Set<X500Principal> issuerX500Principals;
-
-        X509Credentials(PrivateKey privateKey, X509Certificate[] certificates) {
-            // assert privateKey and certificates != null
-            this.privateKey = privateKey;
-            this.certificates = certificates;
-        }
-
-        synchronized Set<X500Principal> getIssuerX500Principals() {
-            // lazy initialization
-            if (issuerX500Principals == null) {
-                issuerX500Principals = new HashSet<X500Principal>();
-                for (int i = 0; i < certificates.length; i++) {
-                    issuerX500Principals.add(
-                                certificates[i].getIssuerX500Principal());
-                }
-            }
-            return issuerX500Principals;
-        }
-    }
-
-    SunX509KeyManagerImpl(KeyStore ks, char[] password) throws KeyStoreException,
-            NoSuchAlgorithmException, UnrecoverableKeyException {
-
-        credentialsMap = new HashMap<String,X509Credentials>();
-        serverAliasCache = new HashMap<String,String[]>();
-        if (ks == null) {
-            return;
-        }
-
-        for (Enumeration<String> aliases = ks.aliases();
-                                        aliases.hasMoreElements(); ) {
-            String alias = aliases.nextElement();
-            if (!ks.isKeyEntry(alias)) {
-                continue;
-            }
-            Key key = ks.getKey(alias, password);
-            if (key instanceof PrivateKey == false) {
-                continue;
-            }
-            Certificate[] certs = ks.getCertificateChain(alias);
-            if ((certs == null) || (certs.length == 0) ||
-                    !(certs[0] instanceof X509Certificate)) {
-                continue;
-            }
-            if (!(certs instanceof X509Certificate[])) {
-                Certificate[] tmp = new X509Certificate[certs.length];
-                System.arraycopy(certs, 0, tmp, 0, certs.length);
-                certs = tmp;
-            }
-
-            X509Credentials cred = new X509Credentials((PrivateKey)key,
-                (X509Certificate[])certs);
-            credentialsMap.put(alias, cred);
-            if (debug != null && Debug.isOn("keymanager")) {
-                System.out.println("***");
-                System.out.println("found key for : " + alias);
-                for (int i = 0; i < certs.length; i++) {
-                    System.out.println("chain [" + i + "] = "
-                    + certs[i]);
-                }
-                System.out.println("***");
-            }
-        }
-    }
-
-    /*
-     * Returns the certificate chain associated with the given alias.
-     *
-     * @return the certificate chain (ordered with the user's certificate first
-     * and the root certificate authority last)
-     */
-    public X509Certificate[] getCertificateChain(String alias) {
-        if (alias == null) {
-            return null;
-        }
-        X509Credentials cred = credentialsMap.get(alias);
-        if (cred == null) {
-            return null;
-        } else {
-            return cred.certificates.clone();
-        }
-    }
-
-    /*
-     * Returns the key associated with the given alias
-     */
-    public PrivateKey getPrivateKey(String alias) {
-        if (alias == null) {
-            return null;
-        }
-        X509Credentials cred = credentialsMap.get(alias);
-        if (cred == null) {
-            return null;
-        } else {
-            return cred.privateKey;
-        }
-    }
-
-    /*
-     * Choose an alias to authenticate the client side of a secure
-     * socket given the public key type and the list of
-     * certificate issuer authorities recognized by the peer (if any).
-     */
-    public String chooseClientAlias(String[] keyTypes, Principal[] issuers,
-            Socket socket) {
-        /*
-         * We currently don't do anything with socket, but
-         * someday we might.  It might be a useful hint for
-         * selecting one of the aliases we get back from
-         * getClientAliases().
-         */
-
-        if (keyTypes == null) {
-            return null;
-        }
-
-        for (int i = 0; i < keyTypes.length; i++) {
-            String[] aliases = getClientAliases(keyTypes[i], issuers);
-            if ((aliases != null) && (aliases.length > 0)) {
-                return aliases[0];
-            }
-        }
-        return null;
-    }
-
-    /*
-     * Choose an alias to authenticate the client side of an
-     * <code>SSLEngine</code> connection given the public key type
-     * and the list of certificate issuer authorities recognized by
-     * the peer (if any).
-     *
-     * @since 1.5
-     */
-    public String chooseEngineClientAlias(String[] keyType,
-            Principal[] issuers, SSLEngine engine) {
-        /*
-         * If we ever start using socket as a selection criteria,
-         * we'll need to adjust this.
-         */
-        return chooseClientAlias(keyType, issuers, null);
-    }
-
-    /*
-     * Choose an alias to authenticate the server side of a secure
-     * socket given the public key type and the list of
-     * certificate issuer authorities recognized by the peer (if any).
-     */
-    public String chooseServerAlias(String keyType,
-            Principal[] issuers, Socket socket) {
-        /*
-         * We currently don't do anything with socket, but
-         * someday we might.  It might be a useful hint for
-         * selecting one of the aliases we get back from
-         * getServerAliases().
-         */
-        if (keyType == null) {
-            return null;
-        }
-
-        String[] aliases;
-
-        if (issuers == null || issuers.length == 0) {
-            aliases = serverAliasCache.get(keyType);
-            if (aliases == null) {
-                aliases = getServerAliases(keyType, issuers);
-                // Cache the result (positive and negative lookups)
-                if (aliases == null) {
-                    aliases = STRING0;
-                }
-                serverAliasCache.put(keyType, aliases);
-            }
-        } else {
-            aliases = getServerAliases(keyType, issuers);
-        }
-        if ((aliases != null) && (aliases.length > 0)) {
-            return aliases[0];
-        }
-        return null;
-    }
-
-    /*
-     * Choose an alias to authenticate the server side of an
-     * <code>SSLEngine</code> connection given the public key type
-     * and the list of certificate issuer authorities recognized by
-     * the peer (if any).
-     *
-     * @since 1.5
-     */
-    public String chooseEngineServerAlias(String keyType,
-            Principal[] issuers, SSLEngine engine) {
-        /*
-         * If we ever start using socket as a selection criteria,
-         * we'll need to adjust this.
-         */
-        return chooseServerAlias(keyType, issuers, null);
-    }
-
-    /*
-     * Get the matching aliases for authenticating the client side of a secure
-     * socket given the public key type and the list of
-     * certificate issuer authorities recognized by the peer (if any).
-     */
-    public String[] getClientAliases(String keyType, Principal[] issuers) {
-        return getAliases(keyType, issuers);
-    }
-
-    /*
-     * Get the matching aliases for authenticating the server side of a secure
-     * socket given the public key type and the list of
-     * certificate issuer authorities recognized by the peer (if any).
-     */
-    public String[] getServerAliases(String keyType, Principal[] issuers) {
-        return getAliases(keyType, issuers);
-    }
-
-    /*
-     * Get the matching aliases for authenticating the either side of a secure
-     * socket given the public key type and the list of
-     * certificate issuer authorities recognized by the peer (if any).
-     *
-     * Issuers comes to us in the form of X500Principal[].
-     */
-    private String[] getAliases(String keyType, Principal[] issuers) {
-        if (keyType == null) {
-            return null;
-        }
-        if (issuers == null) {
-            issuers = new X500Principal[0];
-        }
-        if (issuers instanceof X500Principal[] == false) {
-            // normally, this will never happen but try to recover if it does
-            issuers = convertPrincipals(issuers);
-        }
-        String sigType;
-        if (keyType.contains("_")) {
-            int k = keyType.indexOf("_");
-            sigType = keyType.substring(k + 1);
-            keyType = keyType.substring(0, k);
-        } else {
-            sigType = null;
-        }
-
-        X500Principal[] x500Issuers = (X500Principal[])issuers;
-        // the algorithm below does not produce duplicates, so avoid Set
-        List<String> aliases = new ArrayList<>();
-
-        for (Map.Entry<String,X509Credentials> entry :
-                                                credentialsMap.entrySet()) {
-
-            String alias = entry.getKey();
-            X509Credentials credentials = entry.getValue();
-            X509Certificate[] certs = credentials.certificates;
-
-            if (!keyType.equals(certs[0].getPublicKey().getAlgorithm())) {
-                continue;
-            }
-            if (sigType != null) {
-                if (certs.length > 1) {
-                    // if possible, check the public key in the issuer cert
-                    if (!sigType.equals(certs[1].getPublicKey().getAlgorithm())) {
-                        continue;
-                    }
-                } else {
-                    // Check the signature algorithm of the certificate itself.
-                    // Look for the "withRSA" in "SHA1withRSA", etc.
-                    String sigAlgName =
-                            certs[0].getSigAlgName().toUpperCase(Locale.ENGLISH);
-                    String pattern = "WITH" + sigType.toUpperCase(Locale.ENGLISH);
-                    if (sigAlgName.contains(pattern) == false) {
-                        continue;
-                    }
-                }
-            }
-
-            if (issuers.length == 0) {
-                // no issuer specified, match all
-                aliases.add(alias);
-                if (debug != null && Debug.isOn("keymanager")) {
-                    System.out.println("matching alias: " + alias);
-                }
-            } else {
-                Set<X500Principal> certIssuers =
-                                        credentials.getIssuerX500Principals();
-                for (int i = 0; i < x500Issuers.length; i++) {
-                    if (certIssuers.contains(issuers[i])) {
-                        aliases.add(alias);
-                        if (debug != null && Debug.isOn("keymanager")) {
-                            System.out.println("matching alias: " + alias);
-                        }
-                        break;
-                    }
-                }
-            }
-        }
-
-        String[] aliasStrings = aliases.toArray(STRING0);
-        return ((aliasStrings.length == 0) ? null : aliasStrings);
-    }
-
-    /*
-     * Convert an array of Principals to an array of X500Principals, if
-     * possible. Principals that cannot be converted are ignored.
-     */
-    private static X500Principal[] convertPrincipals(Principal[] principals) {
-        List<X500Principal> list = new ArrayList<>(principals.length);
-        for (int i = 0; i < principals.length; i++) {
-            Principal p = principals[i];
-            if (p instanceof X500Principal) {
-                list.add((X500Principal)p);
-            } else {
-                try {
-                    list.add(new X500Principal(p.getName()));
-                } catch (IllegalArgumentException e) {
-                    // ignore
-                }
-            }
-        }
-        return list.toArray(new X500Principal[list.size()]);
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/TrustManagerFactoryImpl.java b/ojluni/src/main/java/sun/security/ssl/TrustManagerFactoryImpl.java
deleted file mode 100755
index ee2142c..0000000
--- a/ojluni/src/main/java/sun/security/ssl/TrustManagerFactoryImpl.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.util.*;
-import java.io.*;
-import java.math.*;
-import java.security.*;
-import java.security.cert.*;
-import javax.net.ssl.*;
-import java.security.spec.AlgorithmParameterSpec;
-
-import sun.security.validator.Validator;
-
-abstract class TrustManagerFactoryImpl extends TrustManagerFactorySpi {
-
-    private static final Debug debug = Debug.getInstance("ssl");
-    private X509TrustManager trustManager = null;
-    private boolean isInitialized = false;
-
-    TrustManagerFactoryImpl() {
-        // empty
-    }
-
-    protected void engineInit(KeyStore ks) throws KeyStoreException {
-        if (ks == null) {
-            try {
-                ks = getCacertsKeyStore("trustmanager");
-            } catch (SecurityException se) {
-                // eat security exceptions but report other throwables
-                if (debug != null && Debug.isOn("trustmanager")) {
-                    System.out.println(
-                        "SunX509: skip default keystore: " + se);
-                }
-            } catch (Error err) {
-                if (debug != null && Debug.isOn("trustmanager")) {
-                    System.out.println(
-                        "SunX509: skip default keystore: " + err);
-                }
-                throw err;
-            } catch (RuntimeException re) {
-                if (debug != null && Debug.isOn("trustmanager")) {
-                    System.out.println(
-                        "SunX509: skip default keystore: " + re);
-                }
-                throw re;
-            } catch (Exception e) {
-                if (debug != null && Debug.isOn("trustmanager")) {
-                    System.out.println(
-                        "SunX509: skip default keystore: " + e);
-                }
-                throw new KeyStoreException(
-                    "problem accessing trust store" + e);
-            }
-        }
-        trustManager = getInstance(ks);
-        isInitialized = true;
-    }
-
-    abstract X509TrustManager getInstance(KeyStore ks) throws KeyStoreException;
-
-    abstract X509TrustManager getInstance(ManagerFactoryParameters spec)
-            throws InvalidAlgorithmParameterException;
-
-    protected void engineInit(ManagerFactoryParameters spec) throws
-            InvalidAlgorithmParameterException {
-        trustManager = getInstance(spec);
-        isInitialized = true;
-    }
-
-    /**
-     * Returns one trust manager for each type of trust material.
-     */
-    protected TrustManager[] engineGetTrustManagers() {
-        if (!isInitialized) {
-            throw new IllegalStateException(
-                        "TrustManagerFactoryImpl is not initialized");
-        }
-        return new TrustManager[] { trustManager };
-    }
-
-    /*
-     * Try to get an InputStream based on the file we pass in.
-     */
-    private static FileInputStream getFileInputStream(final File file)
-            throws Exception {
-        return AccessController.doPrivileged(
-                new PrivilegedExceptionAction<FileInputStream>() {
-                    public FileInputStream run() throws Exception {
-                        try {
-                            if (file.exists()) {
-                                return new FileInputStream(file);
-                            } else {
-                                return null;
-                            }
-                        } catch (FileNotFoundException e) {
-                            // couldn't find it, oh well.
-                            return null;
-                        }
-                    }
-                });
-    }
-
-    /**
-     * Returns the keystore with the configured CA certificates.
-     */
-    static KeyStore getCacertsKeyStore(String dbgname) throws Exception
-    {
-        String storeFileName = null;
-        File storeFile = null;
-        FileInputStream fis = null;
-        String defaultTrustStoreType;
-        String defaultTrustStoreProvider;
-        final HashMap<String,String> props = new HashMap<>();
-        final String sep = File.separator;
-        KeyStore ks = null;
-
-        AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
-            public Void run() throws Exception {
-                props.put("trustStore", System.getProperty(
-                                "javax.net.ssl.trustStore"));
-                props.put("javaHome", System.getProperty(
-                                        "java.home"));
-                props.put("trustStoreType", System.getProperty(
-                                "javax.net.ssl.trustStoreType",
-                                KeyStore.getDefaultType()));
-                props.put("trustStoreProvider", System.getProperty(
-                                "javax.net.ssl.trustStoreProvider", ""));
-                props.put("trustStorePasswd", System.getProperty(
-                                "javax.net.ssl.trustStorePassword", ""));
-                return null;
-            }
-        });
-
-        /*
-         * Try:
-         *      javax.net.ssl.trustStore  (if this variable exists, stop)
-         *      jssecacerts
-         *      cacerts
-         *
-         * If none exists, we use an empty keystore.
-         */
-
-        storeFileName = props.get("trustStore");
-        if (!"NONE".equals(storeFileName)) {
-            if (storeFileName != null) {
-                storeFile = new File(storeFileName);
-                fis = getFileInputStream(storeFile);
-            } else {
-                String javaHome = props.get("javaHome");
-                storeFile = new File(javaHome + sep + "lib" + sep
-                                                + "security" + sep +
-                                                "jssecacerts");
-                if ((fis = getFileInputStream(storeFile)) == null) {
-                    storeFile = new File(javaHome + sep + "lib" + sep
-                                                + "security" + sep +
-                                                "cacerts");
-                    fis = getFileInputStream(storeFile);
-                }
-            }
-
-            if (fis != null) {
-                storeFileName = storeFile.getPath();
-            } else {
-                storeFileName = "No File Available, using empty keystore.";
-            }
-        }
-
-        defaultTrustStoreType = props.get("trustStoreType");
-        defaultTrustStoreProvider = props.get("trustStoreProvider");
-        if (debug != null && Debug.isOn(dbgname)) {
-            System.out.println("trustStore is: " + storeFileName);
-            System.out.println("trustStore type is : " +
-                                defaultTrustStoreType);
-            System.out.println("trustStore provider is : " +
-                                defaultTrustStoreProvider);
-        }
-
-        /*
-         * Try to initialize trust store.
-         */
-        if (defaultTrustStoreType.length() != 0) {
-            if (debug != null && Debug.isOn(dbgname)) {
-                System.out.println("init truststore");
-            }
-            if (defaultTrustStoreProvider.length() == 0) {
-                ks = KeyStore.getInstance(defaultTrustStoreType);
-            } else {
-                ks = KeyStore.getInstance(defaultTrustStoreType,
-                                        defaultTrustStoreProvider);
-            }
-            char[] passwd = null;
-            String defaultTrustStorePassword = props.get("trustStorePasswd");
-            if (defaultTrustStorePassword.length() != 0)
-                passwd = defaultTrustStorePassword.toCharArray();
-
-            // if trustStore is NONE, fis will be null
-            ks.load(fis, passwd);
-
-            // Zero out the temporary password storage
-            if (passwd != null) {
-                for (int i = 0; i < passwd.length; i++) {
-                    passwd[i] = (char)0;
-                }
-            }
-        }
-
-        if (fis != null) {
-            fis.close();
-        }
-
-        return ks;
-    }
-
-    public static final class SimpleFactory extends TrustManagerFactoryImpl {
-        X509TrustManager getInstance(KeyStore ks) throws KeyStoreException {
-            return new X509TrustManagerImpl(Validator.TYPE_SIMPLE, ks);
-        }
-        X509TrustManager getInstance(ManagerFactoryParameters spec)
-                throws InvalidAlgorithmParameterException {
-            throw new InvalidAlgorithmParameterException
-                ("SunX509 TrustManagerFactory does not use "
-                + "ManagerFactoryParameters");
-        }
-   }
-
-    public static final class PKIXFactory extends TrustManagerFactoryImpl {
-        X509TrustManager getInstance(KeyStore ks) throws KeyStoreException {
-            return new X509TrustManagerImpl(Validator.TYPE_PKIX, ks);
-        }
-        X509TrustManager getInstance(ManagerFactoryParameters spec)
-                throws InvalidAlgorithmParameterException {
-            if (spec instanceof CertPathTrustManagerParameters == false) {
-                throw new InvalidAlgorithmParameterException
-                    ("Parameters must be CertPathTrustManagerParameters");
-            }
-            CertPathParameters params =
-                ((CertPathTrustManagerParameters)spec).getParameters();
-            if (params instanceof PKIXBuilderParameters == false) {
-                throw new InvalidAlgorithmParameterException
-                    ("Encapsulated parameters must be PKIXBuilderParameters");
-            }
-            PKIXBuilderParameters pkixParams = (PKIXBuilderParameters)params;
-            return new X509TrustManagerImpl(Validator.TYPE_PKIX, pkixParams);
-        }
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/X509KeyManagerImpl.java b/ojluni/src/main/java/sun/security/ssl/X509KeyManagerImpl.java
deleted file mode 100755
index 426f5bf..0000000
--- a/ojluni/src/main/java/sun/security/ssl/X509KeyManagerImpl.java
+++ /dev/null
@@ -1,741 +0,0 @@
-/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.lang.ref.*;
-import java.util.*;
-import static java.util.Locale.ENGLISH;
-import java.util.concurrent.atomic.AtomicLong;
-import java.net.Socket;
-
-import java.security.*;
-import java.security.KeyStore.*;
-import java.security.cert.*;
-import java.security.cert.Certificate;
-
-import javax.net.ssl.*;
-
-import sun.security.provider.certpath.AlgorithmChecker;
-
-/**
- * The new X509 key manager implementation. The main differences to the
- * old SunX509 key manager are:
- *  . it is based around the KeyStore.Builder API. This allows it to use
- *    other forms of KeyStore protection or password input (e.g. a
- *    CallbackHandler) or to have keys within one KeyStore protected by
- *    different keys.
- *  . it can use multiple KeyStores at the same time.
- *  . it is explicitly designed to accomodate KeyStores that change over
- *    the lifetime of the process.
- *  . it makes an effort to choose the key that matches best, i.e. one that
- *    is not expired and has the appropriate certificate extensions.
- *
- * Note that this code is not explicitly performance optimzied yet.
- *
- * @author  Andreas Sterbenz
- */
-final class X509KeyManagerImpl extends X509ExtendedKeyManager
-        implements X509KeyManager {
-
-    private static final Debug debug = Debug.getInstance("ssl");
-
-    private final static boolean useDebug =
-                            (debug != null) && Debug.isOn("keymanager");
-
-    // for unit testing only, set via privileged reflection
-    private static Date verificationDate;
-
-    // list of the builders
-    private final List<Builder> builders;
-
-    // counter to generate unique ids for the aliases
-    private final AtomicLong uidCounter;
-
-    // cached entries
-    private final Map<String,Reference<PrivateKeyEntry>> entryCacheMap;
-
-    X509KeyManagerImpl(Builder builder) {
-        this(Collections.singletonList(builder));
-    }
-
-    X509KeyManagerImpl(List<Builder> builders) {
-        this.builders = builders;
-        uidCounter = new AtomicLong();
-        entryCacheMap = Collections.synchronizedMap
-                        (new SizedMap<String,Reference<PrivateKeyEntry>>());
-    }
-
-    // LinkedHashMap with a max size of 10
-    // see LinkedHashMap JavaDocs
-    private static class SizedMap<K,V> extends LinkedHashMap<K,V> {
-        @Override protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
-            return size() > 10;
-        }
-    }
-
-    //
-    // public methods
-    //
-
-    public X509Certificate[] getCertificateChain(String alias) {
-        PrivateKeyEntry entry = getEntry(alias);
-        return entry == null ? null :
-                (X509Certificate[])entry.getCertificateChain();
-    }
-
-    public PrivateKey getPrivateKey(String alias) {
-        PrivateKeyEntry entry = getEntry(alias);
-        return entry == null ? null : entry.getPrivateKey();
-    }
-
-    public String chooseClientAlias(String[] keyTypes, Principal[] issuers,
-            Socket socket) {
-        return chooseAlias(getKeyTypes(keyTypes), issuers, CheckType.CLIENT,
-                        getAlgorithmConstraints(socket));
-    }
-
-    public String chooseEngineClientAlias(String[] keyTypes,
-            Principal[] issuers, SSLEngine engine) {
-        return chooseAlias(getKeyTypes(keyTypes), issuers, CheckType.CLIENT,
-                        getAlgorithmConstraints(engine));
-    }
-
-    public String chooseServerAlias(String keyType,
-            Principal[] issuers, Socket socket) {
-        return chooseAlias(getKeyTypes(keyType), issuers, CheckType.SERVER,
-                        getAlgorithmConstraints(socket));
-    }
-
-    public String chooseEngineServerAlias(String keyType,
-            Principal[] issuers, SSLEngine engine) {
-        return chooseAlias(getKeyTypes(keyType), issuers, CheckType.SERVER,
-                        getAlgorithmConstraints(engine));
-    }
-
-    public String[] getClientAliases(String keyType, Principal[] issuers) {
-        return getAliases(keyType, issuers, CheckType.CLIENT, null);
-    }
-
-    public String[] getServerAliases(String keyType, Principal[] issuers) {
-        return getAliases(keyType, issuers, CheckType.SERVER, null);
-    }
-
-    //
-    // implementation private methods
-    //
-
-    // Gets algorithm constraints of the socket.
-    private AlgorithmConstraints getAlgorithmConstraints(Socket socket) {
-        if (socket != null && socket.isConnected() &&
-                                        socket instanceof SSLSocket) {
-
-            SSLSocket sslSocket = (SSLSocket)socket;
-            SSLSession session = sslSocket.getHandshakeSession();
-
-            if (session != null) {
-                ProtocolVersion protocolVersion =
-                    ProtocolVersion.valueOf(session.getProtocol());
-                if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                    String[] peerSupportedSignAlgs = null;
-
-                    if (session instanceof ExtendedSSLSession) {
-                        ExtendedSSLSession extSession =
-                            (ExtendedSSLSession)session;
-                        peerSupportedSignAlgs =
-                            extSession.getPeerSupportedSignatureAlgorithms();
-                    }
-
-                    return new SSLAlgorithmConstraints(
-                        sslSocket, peerSupportedSignAlgs, true);
-                }
-            }
-
-            return new SSLAlgorithmConstraints(sslSocket, true);
-        }
-
-        return new SSLAlgorithmConstraints((SSLSocket)null, true);
-    }
-
-    // Gets algorithm constraints of the engine.
-    private AlgorithmConstraints getAlgorithmConstraints(SSLEngine engine) {
-        if (engine != null) {
-            SSLSession session = engine.getHandshakeSession();
-            if (session != null) {
-                ProtocolVersion protocolVersion =
-                    ProtocolVersion.valueOf(session.getProtocol());
-                if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                    String[] peerSupportedSignAlgs = null;
-
-                    if (session instanceof ExtendedSSLSession) {
-                        ExtendedSSLSession extSession =
-                            (ExtendedSSLSession)session;
-                        peerSupportedSignAlgs =
-                            extSession.getPeerSupportedSignatureAlgorithms();
-                    }
-
-                    return new SSLAlgorithmConstraints(
-                        engine, peerSupportedSignAlgs, true);
-                }
-            }
-        }
-
-        return new SSLAlgorithmConstraints(engine, true);
-    }
-
-    // we construct the alias we return to JSSE as seen in the code below
-    // a unique id is included to allow us to reliably cache entries
-    // between the calls to getCertificateChain() and getPrivateKey()
-    // even if tokens are inserted or removed
-    private String makeAlias(EntryStatus entry) {
-        return uidCounter.incrementAndGet() + "." + entry.builderIndex + "."
-                + entry.alias;
-    }
-
-    private PrivateKeyEntry getEntry(String alias) {
-        // if the alias is null, return immediately
-        if (alias == null) {
-            return null;
-        }
-
-        // try to get the entry from cache
-        Reference<PrivateKeyEntry> ref = entryCacheMap.get(alias);
-        PrivateKeyEntry entry = (ref != null) ? ref.get() : null;
-        if (entry != null) {
-            return entry;
-        }
-
-        // parse the alias
-        int firstDot = alias.indexOf('.');
-        int secondDot = alias.indexOf('.', firstDot + 1);
-        if ((firstDot == -1) || (secondDot == firstDot)) {
-            // invalid alias
-            return null;
-        }
-        try {
-            int builderIndex = Integer.parseInt
-                                (alias.substring(firstDot + 1, secondDot));
-            String keyStoreAlias = alias.substring(secondDot + 1);
-            Builder builder = builders.get(builderIndex);
-            KeyStore ks = builder.getKeyStore();
-            Entry newEntry = ks.getEntry
-                    (keyStoreAlias, builder.getProtectionParameter(alias));
-            if (newEntry instanceof PrivateKeyEntry == false) {
-                // unexpected type of entry
-                return null;
-            }
-            entry = (PrivateKeyEntry)newEntry;
-            entryCacheMap.put(alias, new SoftReference(entry));
-            return entry;
-        } catch (Exception e) {
-            // ignore
-            return null;
-        }
-    }
-
-    // Class to help verify that the public key algorithm (and optionally
-    // the signature algorithm) of a certificate matches what we need.
-    private static class KeyType {
-
-        final String keyAlgorithm;
-
-        // In TLS 1.2, the signature algorithm  has been obsoleted by the
-        // supported_signature_algorithms, and the certificate type no longer
-        // restricts the algorithm used to sign the certificate.
-        // However, because we don't support certificate type checking other
-        // than rsa_sign, dss_sign and ecdsa_sign, we don't have to check the
-        // protocol version here.
-        final String sigKeyAlgorithm;
-
-        KeyType(String algorithm) {
-            int k = algorithm.indexOf("_");
-            if (k == -1) {
-                keyAlgorithm = algorithm;
-                sigKeyAlgorithm = null;
-            } else {
-                keyAlgorithm = algorithm.substring(0, k);
-                sigKeyAlgorithm = algorithm.substring(k + 1);
-            }
-        }
-
-        boolean matches(Certificate[] chain) {
-            if (!chain[0].getPublicKey().getAlgorithm().equals(keyAlgorithm)) {
-                return false;
-            }
-            if (sigKeyAlgorithm == null) {
-                return true;
-            }
-            if (chain.length > 1) {
-                // if possible, check the public key in the issuer cert
-                return sigKeyAlgorithm.equals(
-                        chain[1].getPublicKey().getAlgorithm());
-            } else {
-                // Check the signature algorithm of the certificate itself.
-                // Look for the "withRSA" in "SHA1withRSA", etc.
-                X509Certificate issuer = (X509Certificate)chain[0];
-                String sigAlgName = issuer.getSigAlgName().toUpperCase(ENGLISH);
-                String pattern = "WITH" + sigKeyAlgorithm.toUpperCase(ENGLISH);
-                return sigAlgName.contains(pattern);
-            }
-        }
-    }
-
-    private static List<KeyType> getKeyTypes(String ... keyTypes) {
-        if ((keyTypes == null) ||
-                (keyTypes.length == 0) || (keyTypes[0] == null)) {
-            return null;
-        }
-        List<KeyType> list = new ArrayList<>(keyTypes.length);
-        for (String keyType : keyTypes) {
-            list.add(new KeyType(keyType));
-        }
-        return list;
-    }
-
-    /*
-     * Return the best alias that fits the given parameters.
-     * The algorithm we use is:
-     *   . scan through all the aliases in all builders in order
-     *   . as soon as we find a perfect match, return
-     *     (i.e. a match with a cert that has appropriate key usage
-     *      and is not expired).
-     *   . if we do not find a perfect match, keep looping and remember
-     *     the imperfect matches
-     *   . at the end, sort the imperfect matches. we prefer expired certs
-     *     with appropriate key usage to certs with the wrong key usage.
-     *     return the first one of them.
-     */
-    private String chooseAlias(List<KeyType> keyTypeList, Principal[] issuers,
-            CheckType checkType, AlgorithmConstraints constraints) {
-        if (keyTypeList == null || keyTypeList.size() == 0) {
-            return null;
-        }
-
-        Set<Principal> issuerSet = getIssuerSet(issuers);
-        List<EntryStatus> allResults = null;
-        for (int i = 0, n = builders.size(); i < n; i++) {
-            try {
-                List<EntryStatus> results = getAliases(i, keyTypeList,
-                                    issuerSet, false, checkType, constraints);
-                if (results != null) {
-                    // the results will either be a single perfect match
-                    // or 1 or more imperfect matches
-                    // if it's a perfect match, return immediately
-                    EntryStatus status = results.get(0);
-                    if (status.checkResult == CheckResult.OK) {
-                        if (useDebug) {
-                            debug.println("KeyMgr: choosing key: " + status);
-                        }
-                        return makeAlias(status);
-                    }
-                    if (allResults == null) {
-                        allResults = new ArrayList<EntryStatus>();
-                    }
-                    allResults.addAll(results);
-                }
-            } catch (Exception e) {
-                // ignore
-            }
-        }
-        if (allResults == null) {
-            if (useDebug) {
-                debug.println("KeyMgr: no matching key found");
-            }
-            return null;
-        }
-        Collections.sort(allResults);
-        if (useDebug) {
-            debug.println("KeyMgr: no good matching key found, "
-                        + "returning best match out of:");
-            debug.println(allResults.toString());
-        }
-        return makeAlias(allResults.get(0));
-    }
-
-    /*
-     * Return all aliases that (approximately) fit the parameters.
-     * These are perfect matches plus imperfect matches (expired certificates
-     * and certificates with the wrong extensions).
-     * The perfect matches will be first in the array.
-     */
-    public String[] getAliases(String keyType, Principal[] issuers,
-            CheckType checkType, AlgorithmConstraints constraints) {
-        if (keyType == null) {
-            return null;
-        }
-
-        Set<Principal> issuerSet = getIssuerSet(issuers);
-        List<KeyType> keyTypeList = getKeyTypes(keyType);
-        List<EntryStatus> allResults = null;
-        for (int i = 0, n = builders.size(); i < n; i++) {
-            try {
-                List<EntryStatus> results = getAliases(i, keyTypeList,
-                                    issuerSet, true, checkType, constraints);
-                if (results != null) {
-                    if (allResults == null) {
-                        allResults = new ArrayList<EntryStatus>();
-                    }
-                    allResults.addAll(results);
-                }
-            } catch (Exception e) {
-                // ignore
-            }
-        }
-        if (allResults == null || allResults.size() == 0) {
-            if (useDebug) {
-                debug.println("KeyMgr: no matching alias found");
-            }
-            return null;
-        }
-        Collections.sort(allResults);
-        if (useDebug) {
-            debug.println("KeyMgr: getting aliases: " + allResults);
-        }
-        return toAliases(allResults);
-    }
-
-    // turn candidate entries into unique aliases we can return to JSSE
-    private String[] toAliases(List<EntryStatus> results) {
-        String[] s = new String[results.size()];
-        int i = 0;
-        for (EntryStatus result : results) {
-            s[i++] = makeAlias(result);
-        }
-        return s;
-    }
-
-    // make a Set out of the array
-    private Set<Principal> getIssuerSet(Principal[] issuers) {
-        if ((issuers != null) && (issuers.length != 0)) {
-            return new HashSet<>(Arrays.asList(issuers));
-        } else {
-            return null;
-        }
-    }
-
-    // a candidate match
-    // identifies the entry by builder and alias
-    // and includes the result of the certificate check
-    private static class EntryStatus implements Comparable<EntryStatus> {
-
-        final int builderIndex;
-        final int keyIndex;
-        final String alias;
-        final CheckResult checkResult;
-
-        EntryStatus(int builderIndex, int keyIndex, String alias,
-                Certificate[] chain, CheckResult checkResult) {
-            this.builderIndex = builderIndex;
-            this.keyIndex = keyIndex;
-            this.alias = alias;
-            this.checkResult = checkResult;
-        }
-
-        public int compareTo(EntryStatus other) {
-            int result = this.checkResult.compareTo(other.checkResult);
-            return (result == 0) ? (this.keyIndex - other.keyIndex) : result;
-        }
-
-        public String toString() {
-            String s = alias + " (verified: " + checkResult + ")";
-            if (builderIndex == 0) {
-                return s;
-            } else {
-                return "Builder #" + builderIndex + ", alias: " + s;
-            }
-        }
-    }
-
-    // enum for the type of certificate check we want to perform
-    // (client or server)
-    // also includes the check code itself
-    private static enum CheckType {
-
-        // enum constant for "no check" (currently not used)
-        NONE(Collections.<String>emptySet()),
-
-        // enum constant for "tls client" check
-        // valid EKU for TLS client: any, tls_client
-        CLIENT(new HashSet<String>(Arrays.asList(new String[] {
-            "2.5.29.37.0", "1.3.6.1.5.5.7.3.2" }))),
-
-        // enum constant for "tls server" check
-        // valid EKU for TLS server: any, tls_server, ns_sgc, ms_sgc
-        SERVER(new HashSet<String>(Arrays.asList(new String[] {
-            "2.5.29.37.0", "1.3.6.1.5.5.7.3.1", "2.16.840.1.113730.4.1",
-            "1.3.6.1.4.1.311.10.3.3" })));
-
-        // set of valid EKU values for this type
-        final Set<String> validEku;
-
-        CheckType(Set<String> validEku) {
-            this.validEku = validEku;
-        }
-
-        private static boolean getBit(boolean[] keyUsage, int bit) {
-            return (bit < keyUsage.length) && keyUsage[bit];
-        }
-
-        // check if this certificate is appropriate for this type of use
-        // first check extensions, if they match, check expiration
-        // note: we may want to move this code into the sun.security.validator
-        // package
-        CheckResult check(X509Certificate cert, Date date) {
-            if (this == NONE) {
-                return CheckResult.OK;
-            }
-
-            // check extensions
-            try {
-                // check extended key usage
-                List<String> certEku = cert.getExtendedKeyUsage();
-                if ((certEku != null) &&
-                        Collections.disjoint(validEku, certEku)) {
-                    // if extension present and it does not contain any of
-                    // the valid EKU OIDs, return extension_mismatch
-                    return CheckResult.EXTENSION_MISMATCH;
-                }
-
-                // check key usage
-                boolean[] ku = cert.getKeyUsage();
-                if (ku != null) {
-                    String algorithm = cert.getPublicKey().getAlgorithm();
-                    boolean kuSignature = getBit(ku, 0);
-                    if (algorithm.equals("RSA")) {
-                        // require either signature bit
-                        // or if server also allow key encipherment bit
-                        if (kuSignature == false) {
-                            if ((this == CLIENT) || (getBit(ku, 2) == false)) {
-                                return CheckResult.EXTENSION_MISMATCH;
-                            }
-                        }
-                    } else if (algorithm.equals("DSA")) {
-                        // require signature bit
-                        if (kuSignature == false) {
-                            return CheckResult.EXTENSION_MISMATCH;
-                        }
-                    } else if (algorithm.equals("DH")) {
-                        // require keyagreement bit
-                        if (getBit(ku, 4) == false) {
-                            return CheckResult.EXTENSION_MISMATCH;
-                        }
-                    } else if (algorithm.equals("EC")) {
-                        // require signature bit
-                        if (kuSignature == false) {
-                            return CheckResult.EXTENSION_MISMATCH;
-                        }
-                        // For servers, also require key agreement.
-                        // This is not totally accurate as the keyAgreement bit
-                        // is only necessary for static ECDH key exchange and
-                        // not ephemeral ECDH. We leave it in for now until
-                        // there are signs that this check causes problems
-                        // for real world EC certificates.
-                        if ((this == SERVER) && (getBit(ku, 4) == false)) {
-                            return CheckResult.EXTENSION_MISMATCH;
-                        }
-                    }
-                }
-            } catch (CertificateException e) {
-                // extensions unparseable, return failure
-                return CheckResult.EXTENSION_MISMATCH;
-            }
-
-            try {
-                cert.checkValidity(date);
-                return CheckResult.OK;
-            } catch (CertificateException e) {
-                return CheckResult.EXPIRED;
-            }
-        }
-    }
-
-    // enum for the result of the extension check
-    // NOTE: the order of the constants is important as they are used
-    // for sorting, i.e. OK is best, followed by EXPIRED and EXTENSION_MISMATCH
-    private static enum CheckResult {
-        OK,                     // ok or not checked
-        EXPIRED,                // extensions valid but cert expired
-        EXTENSION_MISMATCH,     // extensions invalid (expiration not checked)
-    }
-
-    /*
-     * Return a List of all candidate matches in the specified builder
-     * that fit the parameters.
-     * We exclude entries in the KeyStore if they are not:
-     *  . private key entries
-     *  . the certificates are not X509 certificates
-     *  . the algorithm of the key in the EE cert doesn't match one of keyTypes
-     *  . none of the certs is issued by a Principal in issuerSet
-     * Using those entries would not be possible or they would almost
-     * certainly be rejected by the peer.
-     *
-     * In addition to those checks, we also check the extensions in the EE
-     * cert and its expiration. Even if there is a mismatch, we include
-     * such certificates because they technically work and might be accepted
-     * by the peer. This leads to more graceful failure and better error
-     * messages if the cert expires from one day to the next.
-     *
-     * The return values are:
-     *   . null, if there are no matching entries at all
-     *   . if 'findAll' is 'false' and there is a perfect match, a List
-     *     with a single element (early return)
-     *   . if 'findAll' is 'false' and there is NO perfect match, a List
-     *     with all the imperfect matches (expired, wrong extensions)
-     *   . if 'findAll' is 'true', a List with all perfect and imperfect
-     *     matches
-     */
-    private List<EntryStatus> getAliases(int builderIndex,
-            List<KeyType> keyTypes, Set<Principal> issuerSet,
-            boolean findAll, CheckType checkType,
-            AlgorithmConstraints constraints) throws Exception {
-        Builder builder = builders.get(builderIndex);
-        KeyStore ks = builder.getKeyStore();
-        List<EntryStatus> results = null;
-        Date date = verificationDate;
-        boolean preferred = false;
-        for (Enumeration<String> e = ks.aliases(); e.hasMoreElements(); ) {
-            String alias = e.nextElement();
-            // check if it is a key entry (private key or secret key)
-            if (ks.isKeyEntry(alias) == false) {
-                continue;
-            }
-
-            Certificate[] chain = ks.getCertificateChain(alias);
-            if ((chain == null) || (chain.length == 0)) {
-                // must be secret key entry, ignore
-                continue;
-            }
-
-            boolean incompatible = false;
-            for (Certificate cert : chain) {
-                if (cert instanceof X509Certificate == false) {
-                    // not an X509Certificate, ignore this alias
-                    incompatible = true;
-                    break;
-                }
-            }
-            if (incompatible) {
-                continue;
-            }
-
-            // check keytype
-            int keyIndex = -1;
-            int j = 0;
-            for (KeyType keyType : keyTypes) {
-                if (keyType.matches(chain)) {
-                    keyIndex = j;
-                    break;
-                }
-                j++;
-            }
-            if (keyIndex == -1) {
-                if (useDebug) {
-                    debug.println("Ignoring alias " + alias
-                                + ": key algorithm does not match");
-                }
-                continue;
-            }
-            // check issuers
-            if (issuerSet != null) {
-                boolean found = false;
-                for (Certificate cert : chain) {
-                    X509Certificate xcert = (X509Certificate)cert;
-                    if (issuerSet.contains(xcert.getIssuerX500Principal())) {
-                        found = true;
-                        break;
-                    }
-                }
-                if (found == false) {
-                    if (useDebug) {
-                        debug.println("Ignoring alias " + alias
-                                    + ": issuers do not match");
-                    }
-                    continue;
-                }
-            }
-
-            // check the algorithm constraints
-            if (constraints != null &&
-                    !conformsToAlgorithmConstraints(constraints, chain)) {
-
-                if (useDebug) {
-                    debug.println("Ignoring alias " + alias +
-                            ": certificate list does not conform to " +
-                            "algorithm constraints");
-                }
-                continue;
-            }
-
-            if (date == null) {
-                date = new Date();
-            }
-            CheckResult checkResult =
-                    checkType.check((X509Certificate)chain[0], date);
-            EntryStatus status =
-                    new EntryStatus(builderIndex, keyIndex,
-                                        alias, chain, checkResult);
-            if (!preferred && checkResult == CheckResult.OK && keyIndex == 0) {
-                preferred = true;
-            }
-            if (preferred && (findAll == false)) {
-                // if we have a good match and do not need all matches,
-                // return immediately
-                return Collections.singletonList(status);
-            } else {
-                if (results == null) {
-                    results = new ArrayList<EntryStatus>();
-                }
-                results.add(status);
-            }
-        }
-        return results;
-    }
-
-    private static boolean conformsToAlgorithmConstraints(
-            AlgorithmConstraints constraints, Certificate[] chain) {
-
-        AlgorithmChecker checker = new AlgorithmChecker(constraints);
-        try {
-            checker.init(false);
-        } catch (CertPathValidatorException cpve) {
-            // unlikely to happen
-            return false;
-        }
-
-        // It is a forward checker, so we need to check from trust to target.
-        for (int i = chain.length - 1; i >= 0; i--) {
-            Certificate cert = chain[i];
-            try {
-                // We don't care about the unresolved critical extensions.
-                checker.check(cert, Collections.<String>emptySet());
-            } catch (CertPathValidatorException cpve) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/security/ssl/X509TrustManagerImpl.java b/ojluni/src/main/java/sun/security/ssl/X509TrustManagerImpl.java
deleted file mode 100755
index d38e727..0000000
--- a/ojluni/src/main/java/sun/security/ssl/X509TrustManagerImpl.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.ssl;
-
-import java.net.Socket;
-import javax.net.ssl.SSLSession;
-
-import java.util.*;
-import java.security.*;
-import java.security.cert.*;
-
-import javax.net.ssl.*;
-
-import sun.security.validator.*;
-
-import sun.security.util.HostnameChecker;
-
-/**
- * This class implements the SunJSSE X.509 trust manager using the internal
- * validator API in J2SE core. The logic in this class is minimal.<p>
- * <p>
- * This class supports both the Simple validation algorithm from previous
- * JSSE versions and PKIX validation. Currently, it is not possible for the
- * application to specify PKIX parameters other than trust anchors. This will
- * be fixed in a future release using new APIs. When that happens, it may also
- * make sense to separate the Simple and PKIX trust managers into separate
- * classes.
- *
- * @author Andreas Sterbenz
- */
-final class X509TrustManagerImpl extends X509ExtendedTrustManager
-        implements X509TrustManager {
-
-    private final String validatorType;
-
-    /**
-     * The Set of trusted X509Certificates.
-     */
-    private final Collection<X509Certificate> trustedCerts;
-
-    private final PKIXBuilderParameters pkixParams;
-
-    // note that we need separate validator for client and server due to
-    // the different extension checks. They are initialized lazily on demand.
-    private volatile Validator clientValidator, serverValidator;
-
-    private static final Debug debug = Debug.getInstance("ssl");
-
-    X509TrustManagerImpl(String validatorType, KeyStore ks)
-            throws KeyStoreException {
-        this.validatorType = validatorType;
-        this.pkixParams = null;
-        if (ks == null) {
-            trustedCerts = Collections.<X509Certificate>emptySet();
-        } else {
-            trustedCerts = KeyStores.getTrustedCerts(ks);
-        }
-        showTrustedCerts();
-    }
-
-    X509TrustManagerImpl(String validatorType, PKIXBuilderParameters params) {
-        this.validatorType = validatorType;
-        this.pkixParams = params;
-        // create server validator eagerly so that we can conveniently
-        // get the trusted certificates
-        // clients need it anyway eventually, and servers will not mind
-        // the little extra footprint
-        Validator v = getValidator(Validator.VAR_TLS_SERVER);
-        trustedCerts = v.getTrustedCertificates();
-        serverValidator = v;
-        showTrustedCerts();
-    }
-
-    @Override
-    public void checkClientTrusted(X509Certificate chain[], String authType)
-            throws CertificateException {
-        checkTrusted(chain, authType, (Socket)null, true);
-    }
-
-    @Override
-    public void checkServerTrusted(X509Certificate chain[], String authType)
-            throws CertificateException {
-        checkTrusted(chain, authType, (Socket)null, false);
-    }
-
-    @Override
-    public X509Certificate[] getAcceptedIssuers() {
-        X509Certificate[] certsArray = new X509Certificate[trustedCerts.size()];
-        trustedCerts.toArray(certsArray);
-        return certsArray;
-    }
-
-    @Override
-    public void checkClientTrusted(X509Certificate[] chain, String authType,
-                Socket socket) throws CertificateException {
-        checkTrusted(chain, authType, socket, true);
-    }
-
-    @Override
-    public void checkServerTrusted(X509Certificate[] chain, String authType,
-            Socket socket) throws CertificateException {
-        checkTrusted(chain, authType, socket, false);
-    }
-
-    @Override
-    public void checkClientTrusted(X509Certificate[] chain, String authType,
-            SSLEngine engine) throws CertificateException {
-        checkTrusted(chain, authType, engine, true);
-    }
-
-    @Override
-    public void checkServerTrusted(X509Certificate[] chain, String authType,
-            SSLEngine engine) throws CertificateException {
-        checkTrusted(chain, authType, engine, false);
-    }
-
-    private Validator checkTrustedInit(X509Certificate[] chain,
-                                        String authType, boolean isClient) {
-        if (chain == null || chain.length == 0) {
-            throw new IllegalArgumentException(
-                "null or zero-length certificate chain");
-        }
-
-        if (authType == null || authType.length() == 0) {
-            throw new IllegalArgumentException(
-                "null or zero-length authentication type");
-        }
-
-        Validator v = null;
-        if (isClient) {
-            v = clientValidator;
-            if (v == null) {
-                synchronized (this) {
-                    v = clientValidator;
-                    if (v == null) {
-                        v = getValidator(Validator.VAR_TLS_CLIENT);
-                        clientValidator = v;
-                    }
-                }
-            }
-        } else {
-            // assume double checked locking with a volatile flag works
-            // (guaranteed under the new Tiger memory model)
-            v = serverValidator;
-            if (v == null) {
-                synchronized (this) {
-                    v = serverValidator;
-                    if (v == null) {
-                        v = getValidator(Validator.VAR_TLS_SERVER);
-                        serverValidator = v;
-                    }
-                }
-            }
-        }
-
-        return v;
-    }
-
-
-    private void checkTrusted(X509Certificate[] chain, String authType,
-                Socket socket, boolean isClient) throws CertificateException {
-        Validator v = checkTrustedInit(chain, authType, isClient);
-
-        AlgorithmConstraints constraints = null;
-        if ((socket != null) && socket.isConnected() &&
-                                        (socket instanceof SSLSocket)) {
-
-            SSLSocket sslSocket = (SSLSocket)socket;
-            SSLSession session = sslSocket.getHandshakeSession();
-            if (session == null) {
-                throw new CertificateException("No handshake session");
-            }
-
-            // check endpoint identity
-            String identityAlg = sslSocket.getSSLParameters().
-                                        getEndpointIdentificationAlgorithm();
-            if (identityAlg != null && identityAlg.length() != 0) {
-                String hostname = session.getPeerHost();
-                checkIdentity(hostname, chain[0], identityAlg);
-            }
-
-            // create the algorithm constraints
-            ProtocolVersion protocolVersion =
-                ProtocolVersion.valueOf(session.getProtocol());
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                if (session instanceof ExtendedSSLSession) {
-                    ExtendedSSLSession extSession =
-                                    (ExtendedSSLSession)session;
-                    String[] localSupportedSignAlgs =
-                            extSession.getLocalSupportedSignatureAlgorithms();
-
-                    constraints = new SSLAlgorithmConstraints(
-                                    sslSocket, localSupportedSignAlgs, false);
-                } else {
-                    constraints =
-                            new SSLAlgorithmConstraints(sslSocket, false);
-                }
-            } else {
-                constraints = new SSLAlgorithmConstraints(sslSocket, false);
-            }
-        }
-
-        X509Certificate[] trustedChain = null;
-        if (isClient) {
-            trustedChain = validate(v, chain, constraints, null);
-        } else {
-            trustedChain = validate(v, chain, constraints, authType);
-        }
-        if (debug != null && Debug.isOn("trustmanager")) {
-            System.out.println("Found trusted certificate:");
-            System.out.println(trustedChain[trustedChain.length - 1]);
-        }
-    }
-
-    private void checkTrusted(X509Certificate[] chain, String authType,
-            SSLEngine engine, boolean isClient) throws CertificateException {
-        Validator v = checkTrustedInit(chain, authType, isClient);
-
-        AlgorithmConstraints constraints = null;
-        if (engine != null) {
-            SSLSession session = engine.getHandshakeSession();
-            if (session == null) {
-                throw new CertificateException("No handshake session");
-            }
-
-            // check endpoint identity
-            String identityAlg = engine.getSSLParameters().
-                                        getEndpointIdentificationAlgorithm();
-            if (identityAlg != null && identityAlg.length() != 0) {
-                String hostname = session.getPeerHost();
-                checkIdentity(hostname, chain[0], identityAlg);
-            }
-
-            // create the algorithm constraints
-            ProtocolVersion protocolVersion =
-                ProtocolVersion.valueOf(session.getProtocol());
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                if (session instanceof ExtendedSSLSession) {
-                    ExtendedSSLSession extSession =
-                                    (ExtendedSSLSession)session;
-                    String[] localSupportedSignAlgs =
-                            extSession.getLocalSupportedSignatureAlgorithms();
-
-                    constraints = new SSLAlgorithmConstraints(
-                                    engine, localSupportedSignAlgs, false);
-                } else {
-                    constraints =
-                            new SSLAlgorithmConstraints(engine, false);
-                }
-            } else {
-                constraints = new SSLAlgorithmConstraints(engine, false);
-            }
-        }
-
-        X509Certificate[] trustedChain = null;
-        if (isClient) {
-            trustedChain = validate(v, chain, constraints, null);
-        } else {
-            trustedChain = validate(v, chain, constraints, authType);
-        }
-        if (debug != null && Debug.isOn("trustmanager")) {
-            System.out.println("Found trusted certificate:");
-            System.out.println(trustedChain[trustedChain.length - 1]);
-        }
-    }
-
-    private void showTrustedCerts() {
-        if (debug != null && Debug.isOn("trustmanager")) {
-            for (X509Certificate cert : trustedCerts) {
-                System.out.println("adding as trusted cert:");
-                System.out.println("  Subject: "
-                                        + cert.getSubjectX500Principal());
-                System.out.println("  Issuer:  "
-                                        + cert.getIssuerX500Principal());
-                System.out.println("  Algorithm: "
-                                        + cert.getPublicKey().getAlgorithm()
-                                        + "; Serial number: 0x"
-                                        + cert.getSerialNumber().toString(16));
-                System.out.println("  Valid from "
-                                        + cert.getNotBefore() + " until "
-                                        + cert.getNotAfter());
-                System.out.println();
-            }
-        }
-    }
-
-    private Validator getValidator(String variant) {
-        Validator v;
-        if (pkixParams == null) {
-            v = Validator.getInstance(validatorType, variant, trustedCerts);
-        } else {
-            v = Validator.getInstance(validatorType, variant, pkixParams);
-        }
-        return v;
-    }
-
-    private static X509Certificate[] validate(Validator v,
-            X509Certificate[] chain, AlgorithmConstraints constraints,
-            String authType) throws CertificateException {
-        Object o = JsseJce.beginFipsProvider();
-        try {
-            return v.validate(chain, null, constraints, authType);
-        } finally {
-            JsseJce.endFipsProvider(o);
-        }
-    }
-
-    /*
-     * Identify the peer by its certificate and hostname.
-     *
-     * Lifted from sun.net.www.protocol.https.HttpsClient.
-     */
-    static void checkIdentity(String hostname, X509Certificate cert,
-            String algorithm) throws CertificateException {
-        if (algorithm != null && algorithm.length() != 0) {
-            // if IPv6 strip off the "[]"
-            if ((hostname != null) && hostname.startsWith("[") &&
-                    hostname.endsWith("]")) {
-                hostname = hostname.substring(1, hostname.length() - 1);
-            }
-
-            if (algorithm.equalsIgnoreCase("HTTPS")) {
-                HostnameChecker.getInstance(HostnameChecker.TYPE_TLS).match(
-                        hostname, cert);
-            } else if (algorithm.equalsIgnoreCase("LDAP") ||
-                    algorithm.equalsIgnoreCase("LDAPS")) {
-                HostnameChecker.getInstance(HostnameChecker.TYPE_LDAP).match(
-                        hostname, cert);
-            } else {
-                throw new CertificateException(
-                        "Unknown identification algorithm: " + algorithm);
-            }
-        }
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/util/DerIndefLenConverter.java b/ojluni/src/main/java/sun/security/util/DerIndefLenConverter.java
index 78d9e30..cbd5ecc 100755
--- a/ojluni/src/main/java/sun/security/util/DerIndefLenConverter.java
+++ b/ojluni/src/main/java/sun/security/util/DerIndefLenConverter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -156,12 +156,18 @@
         }
         if (isLongForm(lenByte)) {
             lenByte &= LEN_MASK;
-            if (lenByte > 4)
+            if (lenByte > 4) {
                 throw new IOException("Too much data");
-            if ((dataSize - dataPos) < (lenByte + 1))
+            }
+            if ((dataSize - dataPos) < (lenByte + 1)) {
                 throw new IOException("Too little data");
-            for (int i = 0; i < lenByte; i++)
+            }
+            for (int i = 0; i < lenByte; i++) {
                 curLen = (curLen << 8) + (data[dataPos++] & 0xff);
+            }
+            if (curLen < 0) {
+                throw new IOException("Invalid length bytes");
+            }
         } else {
            curLen = (lenByte & LEN_MASK);
         }
@@ -188,10 +194,15 @@
         }
         if (isLongForm(lenByte)) {
             lenByte &= LEN_MASK;
-            for (int i = 0; i < lenByte; i++)
+            for (int i = 0; i < lenByte; i++) {
                 curLen = (curLen << 8) + (data[dataPos++] & 0xff);
-        } else
+            }
+            if (curLen < 0) {
+                throw new IOException("Invalid length bytes");
+            }
+        } else {
             curLen = (lenByte & LEN_MASK);
+        }
         writeLength(curLen);
         writeValue(curLen);
     }
diff --git a/ojluni/src/main/java/sun/security/util/DerInputBuffer.java b/ojluni/src/main/java/sun/security/util/DerInputBuffer.java
index 786e791..b375c60 100755
--- a/ojluni/src/main/java/sun/security/util/DerInputBuffer.java
+++ b/ojluni/src/main/java/sun/security/util/DerInputBuffer.java
@@ -71,6 +71,16 @@
         return retval;
     }
 
+    int getPos() {
+        return pos;
+    }
+
+    byte[] getSlice(int startPos, int size) {
+        byte[] result = new byte[size];
+        System.arraycopy(buf, startPos, result, 0, size);
+        return result;
+    }
+
     int peek() throws IOException {
         if (pos >= count)
             throw new IOException("out of data");
diff --git a/ojluni/src/main/java/sun/security/util/DerInputStream.java b/ojluni/src/main/java/sun/security/util/DerInputStream.java
index e0f77ee..dae8afd 100755
--- a/ojluni/src/main/java/sun/security/util/DerInputStream.java
+++ b/ojluni/src/main/java/sun/security/util/DerInputStream.java
@@ -291,11 +291,28 @@
      *          (used to initialize an auto-growing data structure)
      * @return array of the values in the sequence
      */
-    public DerValue[] getSequence(int startLen) throws IOException {
+    public DerValue[] getSequence(int startLen,
+            boolean originalEncodedFormRetained) throws IOException {
         tag = (byte)buffer.read();
         if (tag != DerValue.tag_Sequence)
             throw new IOException("Sequence tag error");
-        return readVector(startLen);
+        return readVector(startLen, originalEncodedFormRetained);
+    }
+
+    /**
+     * Return a sequence of encoded entities.  ASN.1 sequences are
+     * ordered, and they are often used, like a "struct" in C or C++,
+     * to group data values.  They may have optional or context
+     * specific values.
+     *
+     * @param startLen guess about how long the sequence will be
+     *          (used to initialize an auto-growing data structure)
+     * @return array of the values in the sequence
+     */
+    public DerValue[] getSequence(int startLen) throws IOException {
+        return getSequence(
+                startLen,
+                false); // no need to retain original encoded form
     }
 
     /**
@@ -328,13 +345,22 @@
      */
     public DerValue[] getSet(int startLen, boolean implicit)
         throws IOException {
+        return getSet(
+            startLen,
+            implicit,
+            false); // no need to retain original encoded form
+    }
+
+    public DerValue[] getSet(int startLen, boolean implicit,
+            boolean originalEncodedFormRetained)
+        throws IOException {
         tag = (byte)buffer.read();
         if (!implicit) {
             if (tag != DerValue.tag_Set) {
                 throw new IOException("Set tag error");
             }
         }
-        return (readVector(startLen));
+        return (readVector(startLen, originalEncodedFormRetained));
     }
 
     /*
@@ -343,6 +369,18 @@
      * this same helper routine.
      */
     protected DerValue[] readVector(int startLen) throws IOException {
+        return readVector(
+            startLen,
+            false); // no need to retain original encoded form
+    }
+
+    /*
+     * Read a "vector" of values ... set or sequence have the
+     * same encoding, except for the initial tag, so both use
+     * this same helper routine.
+     */
+    protected DerValue[] readVector(int startLen,
+            boolean originalEncodedFormRetained) throws IOException {
         DerInputStream  newstr;
 
         byte lenByte = (byte)buffer.read();
@@ -387,7 +425,7 @@
         DerValue value;
 
         do {
-            value = new DerValue(newstr.buffer);
+            value = new DerValue(newstr.buffer, originalEncodedFormRetained);
             vec.addElement(value);
         } while (newstr.available() > 0);
 
@@ -566,6 +604,10 @@
                 value <<= 8;
                 value += 0x0ff & in.read();
             }
+            if (value < 0) {
+                throw new IOException("DerInputStream.getLength(): "
+                        + "Invalid length bytes");
+            }
         }
         return value;
     }
diff --git a/ojluni/src/main/java/sun/security/util/DerValue.java b/ojluni/src/main/java/sun/security/util/DerValue.java
index beb51c1..6bca1f7 100755
--- a/ojluni/src/main/java/sun/security/util/DerValue.java
+++ b/ojluni/src/main/java/sun/security/util/DerValue.java
@@ -72,6 +72,12 @@
 
     private int                 length;
 
+    /**
+     * The original encoded form of the whole value (tag, length, and value)
+     * or null if the form was not provided or was not retained during parsing.
+     */
+    private byte[]              originalEncodedForm;
+
     /*
      * The type starts at the first byte of the encoding, and
      * is one of these tag_* values.  That may be all the type
@@ -243,10 +249,12 @@
     /*
      * package private
      */
-    DerValue(DerInputBuffer in) throws IOException {
+    DerValue(DerInputBuffer in, boolean originalEncodedFormRetained)
+            throws IOException {
         // XXX must also parse BER-encoded constructed
         // values such as sequences, sets...
 
+        int startPosInInput = in.getPos();
         tag = (byte)in.read();
         byte lenByte = (byte)in.read();
         length = DerInputStream.getLength((lenByte & 0xff), in);
@@ -281,6 +289,11 @@
 
             in.skip(length);
         }
+
+        if (originalEncodedFormRetained) {
+            int consumed = in.getPos() - startPosInInput;
+            originalEncodedForm = in.getSlice(startPosInInput, consumed);
+        }
     }
 
     /**
@@ -822,6 +835,15 @@
     }
 
     /**
+     * Returns the original encoded form or {@code null} if the form was not
+     * retained or is not available.
+     */
+    public byte[] getOriginalEncodedForm() {
+        return (originalEncodedForm != null)
+                ? originalEncodedForm.clone() : null;
+    }
+
+    /**
      * Returns a DER-encoded value, such that if it's passed to the
      * DerValue constructor, a value equivalent to "this" is returned.
      *
diff --git a/ojluni/src/main/java/sun/security/util/HostnameChecker.java b/ojluni/src/main/java/sun/security/util/HostnameChecker.java
deleted file mode 100755
index b3e8971..0000000
--- a/ojluni/src/main/java/sun/security/util/HostnameChecker.java
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.util;
-
-import java.io.IOException;
-import java.util.*;
-
-import java.security.Principal;
-import java.security.cert.*;
-
-import javax.security.auth.x500.X500Principal;
-
-import sun.security.ssl.Krb5Helper;
-import sun.security.x509.X500Name;
-
-import sun.net.util.IPAddressUtil;
-
-/**
- * Class to check hostnames against the names specified in a certificate as
- * required for TLS and LDAP.
- *
- */
-public class HostnameChecker {
-
-    // Constant for a HostnameChecker for TLS
-    public final static byte TYPE_TLS = 1;
-    private final static HostnameChecker INSTANCE_TLS =
-                                        new HostnameChecker(TYPE_TLS);
-
-    // Constant for a HostnameChecker for LDAP
-    public final static byte TYPE_LDAP = 2;
-    private final static HostnameChecker INSTANCE_LDAP =
-                                        new HostnameChecker(TYPE_LDAP);
-
-    // constants for subject alt names of type DNS and IP
-    private final static int ALTNAME_DNS = 2;
-    private final static int ALTNAME_IP  = 7;
-
-    // the algorithm to follow to perform the check. Currently unused.
-    private final byte checkType;
-
-    private HostnameChecker(byte checkType) {
-        this.checkType = checkType;
-    }
-
-    /**
-     * Get a HostnameChecker instance. checkType should be one of the
-     * TYPE_* constants defined in this class.
-     */
-    public static HostnameChecker getInstance(byte checkType) {
-        if (checkType == TYPE_TLS) {
-            return INSTANCE_TLS;
-        } else if (checkType == TYPE_LDAP) {
-            return INSTANCE_LDAP;
-        }
-        throw new IllegalArgumentException("Unknown check type: " + checkType);
-    }
-
-    /**
-     * Perform the check.
-     *
-     * @exception CertificateException if the name does not match any of
-     * the names specified in the certificate
-     */
-    public void match(String expectedName, X509Certificate cert)
-            throws CertificateException {
-        if (isIpAddress(expectedName)) {
-           matchIP(expectedName, cert);
-        } else {
-           matchDNS(expectedName, cert);
-        }
-    }
-
-    /**
-     * Perform the check for Kerberos.
-     */
-    public static boolean match(String expectedName, Principal principal) {
-        String hostName = getServerName(principal);
-        return (expectedName.equalsIgnoreCase(hostName));
-    }
-
-    /**
-     * Return the Server name from Kerberos principal.
-     */
-    public static String getServerName(Principal principal) {
-        return Krb5Helper.getPrincipalHostName(principal);
-    }
-
-    /**
-     * Test whether the given hostname looks like a literal IPv4 or IPv6
-     * address. The hostname does not need to be a fully qualified name.
-     *
-     * This is not a strict check that performs full input validation.
-     * That means if the method returns true, name need not be a correct
-     * IP address, rather that it does not represent a valid DNS hostname.
-     * Likewise for IP addresses when it returns false.
-     */
-    private static boolean isIpAddress(String name) {
-        if (IPAddressUtil.isIPv4LiteralAddress(name) ||
-            IPAddressUtil.isIPv6LiteralAddress(name)) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Check if the certificate allows use of the given IP address.
-     *
-     * From RFC2818:
-     * In some cases, the URI is specified as an IP address rather than a
-     * hostname. In this case, the iPAddress subjectAltName must be present
-     * in the certificate and must exactly match the IP in the URI.
-     */
-    private static void matchIP(String expectedIP, X509Certificate cert)
-            throws CertificateException {
-        Collection<List<?>> subjAltNames = cert.getSubjectAlternativeNames();
-        if (subjAltNames == null) {
-            throw new CertificateException
-                                ("No subject alternative names present");
-        }
-        for (List<?> next : subjAltNames) {
-            // For IP address, it needs to be exact match
-            if (((Integer)next.get(0)).intValue() == ALTNAME_IP) {
-                String ipAddress = (String)next.get(1);
-                if (expectedIP.equalsIgnoreCase(ipAddress)) {
-                    return;
-                }
-            }
-        }
-        throw new CertificateException("No subject alternative " +
-                        "names matching " + "IP address " +
-                        expectedIP + " found");
-    }
-
-    /**
-     * Check if the certificate allows use of the given DNS name.
-     *
-     * From RFC2818:
-     * If a subjectAltName extension of type dNSName is present, that MUST
-     * be used as the identity. Otherwise, the (most specific) Common Name
-     * field in the Subject field of the certificate MUST be used. Although
-     * the use of the Common Name is existing practice, it is deprecated and
-     * Certification Authorities are encouraged to use the dNSName instead.
-     *
-     * Matching is performed using the matching rules specified by
-     * [RFC2459].  If more than one identity of a given type is present in
-     * the certificate (e.g., more than one dNSName name, a match in any one
-     * of the set is considered acceptable.)
-     */
-    private void matchDNS(String expectedName, X509Certificate cert)
-            throws CertificateException {
-        Collection<List<?>> subjAltNames = cert.getSubjectAlternativeNames();
-        if (subjAltNames != null) {
-            boolean foundDNS = false;
-            for ( List<?> next : subjAltNames) {
-                if (((Integer)next.get(0)).intValue() == ALTNAME_DNS) {
-                    foundDNS = true;
-                    String dnsName = (String)next.get(1);
-                    if (isMatched(expectedName, dnsName)) {
-                        return;
-                    }
-                }
-            }
-            if (foundDNS) {
-                // if certificate contains any subject alt names of type DNS
-                // but none match, reject
-                throw new CertificateException("No subject alternative DNS "
-                        + "name matching " + expectedName + " found.");
-            }
-        }
-        X500Name subjectName = getSubjectX500Name(cert);
-        DerValue derValue = subjectName.findMostSpecificAttribute
-                                                    (X500Name.commonName_oid);
-        if (derValue != null) {
-            try {
-                if (isMatched(expectedName, derValue.getAsString())) {
-                    return;
-                }
-            } catch (IOException e) {
-                // ignore
-            }
-        }
-        String msg = "No name matching " + expectedName + " found";
-        throw new CertificateException(msg);
-    }
-
-
-    /**
-     * Return the subject of a certificate as X500Name, by reparsing if
-     * necessary. X500Name should only be used if access to name components
-     * is required, in other cases X500Principal is to be prefered.
-     *
-     * This method is currently used from within JSSE, do not remove.
-     */
-    public static X500Name getSubjectX500Name(X509Certificate cert)
-            throws CertificateParsingException {
-        try {
-            Principal subjectDN = cert.getSubjectDN();
-            if (subjectDN instanceof X500Name) {
-                return (X500Name)subjectDN;
-            } else {
-                X500Principal subjectX500 = cert.getSubjectX500Principal();
-                return new X500Name(subjectX500.getEncoded());
-            }
-        } catch (IOException e) {
-            throw(CertificateParsingException)
-                new CertificateParsingException().initCause(e);
-        }
-    }
-
-
-    /**
-     * Returns true if name matches against template.<p>
-     *
-     * The matching is performed as per RFC 2818 rules for TLS and
-     * RFC 2830 rules for LDAP.<p>
-     *
-     * The <code>name</code> parameter should represent a DNS name.
-     * The <code>template</code> parameter
-     * may contain the wildcard character *
-     */
-    private boolean isMatched(String name, String template) {
-        if (checkType == TYPE_TLS) {
-            return matchAllWildcards(name, template);
-        } else if (checkType == TYPE_LDAP) {
-            return matchLeftmostWildcard(name, template);
-        } else {
-            return false;
-        }
-    }
-
-
-    /**
-     * Returns true if name matches against template.<p>
-     *
-     * According to RFC 2818, section 3.1 -
-     * Names may contain the wildcard character * which is
-     * considered to match any single domain name component
-     * or component fragment.
-     * E.g., *.a.com matches foo.a.com but not
-     * bar.foo.a.com. f*.com matches foo.com but not bar.com.
-     */
-    private static boolean matchAllWildcards(String name,
-         String template) {
-        name = name.toLowerCase();
-        template = template.toLowerCase();
-        StringTokenizer nameSt = new StringTokenizer(name, ".");
-        StringTokenizer templateSt = new StringTokenizer(template, ".");
-
-        if (nameSt.countTokens() != templateSt.countTokens()) {
-            return false;
-        }
-
-        while (nameSt.hasMoreTokens()) {
-            if (!matchWildCards(nameSt.nextToken(),
-                        templateSt.nextToken())) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-
-    /**
-     * Returns true if name matches against template.<p>
-     *
-     * As per RFC 2830, section 3.6 -
-     * The "*" wildcard character is allowed.  If present, it applies only
-     * to the left-most name component.
-     * E.g. *.bar.com would match a.bar.com, b.bar.com, etc. but not
-     * bar.com.
-     */
-    private static boolean matchLeftmostWildcard(String name,
-                         String template) {
-        name = name.toLowerCase();
-        template = template.toLowerCase();
-
-        // Retreive leftmost component
-        int templateIdx = template.indexOf(".");
-        int nameIdx = name.indexOf(".");
-
-        if (templateIdx == -1)
-            templateIdx = template.length();
-        if (nameIdx == -1)
-            nameIdx = name.length();
-
-        if (matchWildCards(name.substring(0, nameIdx),
-            template.substring(0, templateIdx))) {
-
-            // match rest of the name
-            return template.substring(templateIdx).equals(
-                        name.substring(nameIdx));
-        } else {
-            return false;
-        }
-    }
-
-
-    /**
-     * Returns true if the name matches against the template that may
-     * contain wildcard char * <p>
-     */
-    private static boolean matchWildCards(String name, String template) {
-
-        int wildcardIdx = template.indexOf("*");
-        if (wildcardIdx == -1)
-            return name.equals(template);
-
-        boolean isBeginning = true;
-        String beforeWildcard = "";
-        String afterWildcard = template;
-
-        while (wildcardIdx != -1) {
-
-            // match in sequence the non-wildcard chars in the template.
-            beforeWildcard = afterWildcard.substring(0, wildcardIdx);
-            afterWildcard = afterWildcard.substring(wildcardIdx + 1);
-
-            int beforeStartIdx = name.indexOf(beforeWildcard);
-            if ((beforeStartIdx == -1) ||
-                        (isBeginning && beforeStartIdx != 0)) {
-                return false;
-            }
-            isBeginning = false;
-
-            // update the match scope
-            name = name.substring(beforeStartIdx + beforeWildcard.length());
-            wildcardIdx = afterWildcard.indexOf("*");
-        }
-        return name.endsWith(afterWildcard);
-    }
-}
diff --git a/ojluni/src/main/java/sun/security/x509/X509CertImpl.java b/ojluni/src/main/java/sun/security/x509/X509CertImpl.java
index 5ff1c9b..4f7f81b 100755
--- a/ojluni/src/main/java/sun/security/x509/X509CertImpl.java
+++ b/ojluni/src/main/java/sun/security/x509/X509CertImpl.java
@@ -315,6 +315,24 @@
     }
 
     /**
+     * Unmarshal a certificate from its encoded form, parsing a DER value.
+     * This form of constructor is used by agents which need to examine
+     * and use certificate contents.
+     *
+     * @param derVal the der value containing the encoded cert.
+     * @exception CertificateException on parsing and initialization errors.
+     */
+    public X509CertImpl(DerValue derVal, byte[] encoded)
+        throws CertificateException {
+        try {
+            parse(derVal, encoded);
+        } catch (IOException e) {
+            signedCert = null;
+            throw new CertificateException("Unable to initialize, " + e, e);
+        }
+    }
+
+    /**
      * Appends the certificate to an output stream.
      *
      * @param out an input stream to which the certificate is appended.
@@ -1770,6 +1788,24 @@
      */
     private void parse(DerValue val)
     throws CertificateException, IOException {
+        parse(
+            val,
+            null // use re-encoded form of val as the encoded form
+            );
+    }
+
+    /*
+     * Cert is a SIGNED ASN.1 macro, a three elment sequence:
+     *
+     *  - Data to be signed (ToBeSigned) -- the "raw" cert
+     *  - Signature algorithm (SigAlgId)
+     *  - The signature bits
+     *
+     * This routine unmarshals the certificate, saving the signature
+     * parts away for later verification.
+     */
+    private void parse(DerValue val, byte[] originalEncodedForm)
+    throws CertificateException, IOException {
         // check if can over write the certificate
         if (readOnly)
             throw new CertificateParsingException(
@@ -1779,7 +1815,9 @@
             throw new CertificateParsingException(
                       "invalid DER-encoded certificate data");
 
-        signedCert = val.toByteArray();
+        signedCert =
+                (originalEncodedForm != null)
+                        ? originalEncodedForm : val.toByteArray();
         DerValue[] seq = new DerValue[3];
 
         seq[0] = val.data.getDerValue();
diff --git a/ojluni/src/main/native/java_util_zip_ZipFile.c b/ojluni/src/main/native/java_util_zip_ZipFile.c
index 7280d97..5353ff4 100644
--- a/ojluni/src/main/native/java_util_zip_ZipFile.c
+++ b/ojluni/src/main/native/java_util_zip_ZipFile.c
@@ -156,6 +156,12 @@
     ZIP_Close(jlong_to_ptr(zfile));
 }
 
+JNIEXPORT jint JNICALL
+ZipFile_getFileDescriptor(JNIEnv *env, jclass cls, jlong zfile) {
+    jzfile *zip = jlong_to_ptr(zfile);
+    return zip->zfd;
+}
+
 JNIEXPORT jlong JNICALL
 ZipFile_getEntry(JNIEnv *env, jclass cls, jlong zfile,
                  jbyteArray name, jboolean addSlash)
@@ -390,6 +396,7 @@
 }
 
 static JNINativeMethod gMethods[] = {
+  NATIVE_METHOD(ZipFile, getFileDescriptor, "(J)I"),
   NATIVE_METHOD(ZipFile, getEntry, "(J[BZ)J"),
   NATIVE_METHOD(ZipFile, freeEntry, "(JJ)V"),
   NATIVE_METHOD(ZipFile, getNextEntry, "(JI)J"),
diff --git a/ojluni/src/main/native/zip_util.c b/ojluni/src/main/native/zip_util.c
index a4dbe14..5a2a0b8 100644
--- a/ojluni/src/main/native/zip_util.c
+++ b/ojluni/src/main/native/zip_util.c
@@ -142,7 +142,7 @@
 }
 
 static int
-ZFILE_read(ZFILE zfd, char *buf, jint nbytes) {
+ZFILE_read(ZFILE zfd, char *buf, jint nbytes, jlong offset) {
 #ifdef WIN32
     return (int) IO_Read(zfd, buf, nbytes);
 #else
@@ -154,7 +154,7 @@
      * JVM_IO_INTR is tricky and could cause undesired side effect. So we decided
      * to simply call "read" on Solaris/Linux. See details in bug 6304463.
      */
-    return read(zfd, buf, nbytes);
+    return pread(zfd, buf, nbytes, offset);
 #endif
 }
 
@@ -183,11 +183,11 @@
 }
 
 /*
- * Reads len bytes of data into buf.
+ * Reads len bytes of data from the specified offset into buf.
  * Returns 0 if all bytes could be read, otherwise returns -1.
  */
 static int
-readFully(ZFILE zfd, void *buf, jlong len) {
+readFullyAt(ZFILE zfd, void *buf, jlong len, jlong offset) {
   char *bp = (char *) buf;
 
   while (len > 0) {
@@ -195,9 +195,10 @@
         jint count = (len < limit) ?
             (jint) len :
             (jint) limit;
-        jint n = ZFILE_read(zfd, bp, count);
+        jint n = ZFILE_read(zfd, bp, count, offset);
         if (n > 0) {
             bp += n;
+            offset += n;
             len -= n;
         } else if (n == JVM_IO_ERR && errno == EINTR) {
           /* Retry after EINTR (interrupted by signal).
@@ -210,19 +211,6 @@
     return 0;
 }
 
-/*
- * Reads len bytes of data from the specified offset into buf.
- * Returns 0 if all bytes could be read, otherwise returns -1.
- */
-static int
-readFullyAt(ZFILE zfd, void *buf, jlong len, jlong offset)
-{
-    if (IO_Lseek(zfd, offset, SEEK_SET) == -1) {
-        return -1; /* lseek failure. */
-    }
-
-    return readFully(zfd, buf, len);
-}
 
 /*
  * Allocates a new zip file object for the specified file name.
@@ -877,14 +865,17 @@
         return NULL;
     }
 
-    // Assumption, zfd refers to start of file. Trivially, reuse errbuf.
-    if (readFully(zfd, errbuf, 4) != -1) {  // errors will be handled later
+    // Trivially, reuse errbuf.
+    if (readFullyAt(zfd, errbuf, 4, 0 /* offset */) != -1) {  // errors will be handled later
         if (GETSIG(errbuf) == LOCSIG)
             zip->locsig = JNI_TRUE;
         else
             zip->locsig = JNI_FALSE;
     }
 
+    // This lseek is safe because it happens during construction of the ZipFile
+    // object. We must take care not to perform any operations that change the
+    // offset after (see b/30407219).
     len = zip->len = IO_Lseek(zfd, 0, SEEK_END);
     if (len <= 0) {
         if (len == 0) { /* zip file is empty */
@@ -984,7 +975,7 @@
     censize = CENSIZE(cen);
     if (censize <= bufsize) return cen;
     if ((cen = realloc(cen, censize)) == NULL)              goto Catch;
-    if (readFully(zfd, cen+bufsize, censize-bufsize) == -1) goto Catch;
+    if (readFullyAt(zfd, cen+bufsize, censize-bufsize, cenpos + bufsize) == -1) goto Catch;
     return cen;
 
  Catch:
diff --git a/openjdk_java_files.mk b/openjdk_java_files.mk
index 7981058..d746447 100644
--- a/openjdk_java_files.mk
+++ b/openjdk_java_files.mk
@@ -1042,7 +1042,6 @@
     ojluni/src/main/java/sun/reflect/CallerSensitive.java \
 
 openjdk_java_files := \
-    ojluni/src/main/java/com/sun/net/ssl/internal/ssl/Provider.java \
     ojluni/src/main/java/com/sun/net/ssl/internal/ssl/X509ExtendedTrustManager.java \
     ojluni/src/main/java/com/sun/security/cert/internal/x509/X509V1CertImpl.java \
     ojluni/src/main/java/java/beans/ChangeListenerMap.java \
@@ -1168,11 +1167,6 @@
     ojluni/src/main/java/sun/net/www/protocol/http/NegotiateAuthentication.java \
     ojluni/src/main/java/sun/net/www/protocol/http/Negotiator.java \
     ojluni/src/main/java/sun/net/www/protocol/http/NTLMAuthenticationProxy.java \
-    ojluni/src/main/java/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java \
-    ojluni/src/main/java/sun/net/www/protocol/https/DelegateHttpsURLConnection.java \
-    ojluni/src/main/java/sun/net/www/protocol/https/Handler.java \
-    ojluni/src/main/java/sun/net/www/protocol/https/HttpsClient.java \
-    ojluni/src/main/java/sun/net/www/protocol/https/HttpsURLConnectionImpl.java \
     ojluni/src/main/java/sun/net/www/protocol/jar/Handler.java \
     ojluni/src/main/java/sun/net/www/protocol/jar/JarFileFactory.java \
     ojluni/src/main/java/sun/net/www/protocol/jar/JarURLConnection.java \
@@ -1309,61 +1303,6 @@
     ojluni/src/main/java/sun/security/provider/certpath/X509CertificatePair.java \
     ojluni/src/main/java/sun/security/provider/X509Factory.java \
     ojluni/src/main/java/sun/security/rsa/SunRsaSignEntries.java \
-    ojluni/src/main/java/sun/security/ssl/Alerts.java \
-    ojluni/src/main/java/sun/security/ssl/AppInputStream.java \
-    ojluni/src/main/java/sun/security/ssl/AppOutputStream.java \
-    ojluni/src/main/java/sun/security/ssl/BaseSSLSocketImpl.java \
-    ojluni/src/main/java/sun/security/ssl/ByteBufferInputStream.java \
-    ojluni/src/main/java/sun/security/ssl/CipherBox.java \
-    ojluni/src/main/java/sun/security/ssl/CipherSuite.java \
-    ojluni/src/main/java/sun/security/ssl/CipherSuiteList.java \
-    ojluni/src/main/java/sun/security/ssl/ClientHandshaker.java \
-    ojluni/src/main/java/sun/security/ssl/Debug.java \
-    ojluni/src/main/java/sun/security/ssl/DHClientKeyExchange.java \
-    ojluni/src/main/java/sun/security/ssl/DHCrypt.java \
-    ojluni/src/main/java/sun/security/ssl/ECDHClientKeyExchange.java \
-    ojluni/src/main/java/sun/security/ssl/ECDHCrypt.java \
-    ojluni/src/main/java/sun/security/ssl/EngineArgs.java \
-    ojluni/src/main/java/sun/security/ssl/EngineInputRecord.java \
-    ojluni/src/main/java/sun/security/ssl/EngineOutputRecord.java \
-    ojluni/src/main/java/sun/security/ssl/EngineWriter.java \
-    ojluni/src/main/java/sun/security/ssl/EphemeralKeyManager.java \
-    ojluni/src/main/java/sun/security/ssl/HandshakeHash.java \
-    ojluni/src/main/java/sun/security/ssl/HandshakeInStream.java \
-    ojluni/src/main/java/sun/security/ssl/HandshakeMessage.java \
-    ojluni/src/main/java/sun/security/ssl/HandshakeOutStream.java \
-    ojluni/src/main/java/sun/security/ssl/Handshaker.java \
-    ojluni/src/main/java/sun/security/ssl/HelloExtensions.java \
-    ojluni/src/main/java/sun/security/ssl/InputRecord.java \
-    ojluni/src/main/java/sun/security/ssl/JsseJce.java \
-    ojluni/src/main/java/sun/security/ssl/KerberosClientKeyExchange.java \
-    ojluni/src/main/java/sun/security/ssl/Krb5Helper.java \
-    ojluni/src/main/java/sun/security/ssl/Krb5Proxy.java \
-    ojluni/src/main/java/sun/security/ssl/MAC.java \
-    ojluni/src/main/java/sun/security/ssl/OutputRecord.java \
-    ojluni/src/main/java/sun/security/ssl/ProtocolList.java \
-    ojluni/src/main/java/sun/security/ssl/ProtocolVersion.java \
-    ojluni/src/main/java/sun/security/ssl/RandomCookie.java \
-    ojluni/src/main/java/sun/security/ssl/Record.java \
-    ojluni/src/main/java/sun/security/ssl/RSAClientKeyExchange.java \
-    ojluni/src/main/java/sun/security/ssl/RSASignature.java \
-    ojluni/src/main/java/sun/security/ssl/ServerHandshaker.java \
-    ojluni/src/main/java/sun/security/ssl/SessionId.java \
-    ojluni/src/main/java/sun/security/ssl/SignatureAndHashAlgorithm.java \
-    ojluni/src/main/java/sun/security/ssl/SSLAlgorithmConstraints.java \
-    ojluni/src/main/java/sun/security/ssl/SSLContextImpl.java \
-    ojluni/src/main/java/sun/security/ssl/SSLEngineImpl.java \
-    ojluni/src/main/java/sun/security/ssl/SSLServerSocketFactoryImpl.java \
-    ojluni/src/main/java/sun/security/ssl/SSLServerSocketImpl.java \
-    ojluni/src/main/java/sun/security/ssl/SSLSessionContextImpl.java \
-    ojluni/src/main/java/sun/security/ssl/SSLSessionImpl.java \
-    ojluni/src/main/java/sun/security/ssl/SSLSocketFactoryImpl.java \
-    ojluni/src/main/java/sun/security/ssl/SSLSocketImpl.java \
-    ojluni/src/main/java/sun/security/ssl/SunJSSE.java \
-    ojluni/src/main/java/sun/security/ssl/SunX509KeyManagerImpl.java \
-    ojluni/src/main/java/sun/security/ssl/TrustManagerFactoryImpl.java \
-    ojluni/src/main/java/sun/security/ssl/X509KeyManagerImpl.java \
-    ojluni/src/main/java/sun/security/ssl/X509TrustManagerImpl.java \
     ojluni/src/main/java/sun/security/timestamp/TimestampToken.java \
     ojluni/src/main/java/sun/security/util/BitArray.java \
     ojluni/src/main/java/sun/security/util/ByteArrayLexOrder.java \
@@ -1377,7 +1316,6 @@
     ojluni/src/main/java/sun/security/util/DerOutputStream.java \
     ojluni/src/main/java/sun/security/util/DerValue.java \
     ojluni/src/main/java/sun/security/util/DisabledAlgorithmConstraints.java \
-    ojluni/src/main/java/sun/security/util/HostnameChecker.java \
     ojluni/src/main/java/sun/security/util/KeyUtil.java \
     ojluni/src/main/java/sun/security/util/Length.java \
     ojluni/src/main/java/sun/security/util/ManifestDigester.java \
diff --git a/support/src/test/java/libcore/java/security/StandardNames.java b/support/src/test/java/libcore/java/security/StandardNames.java
index d414d4b..675aa3d 100644
--- a/support/src/test/java/libcore/java/security/StandardNames.java
+++ b/support/src/test/java/libcore/java/security/StandardNames.java
@@ -988,6 +988,14 @@
             "TLS_PSK_WITH_AES_256_CBC_SHA"
             );
 
+    // Should be updated to match BoringSSL's defaults when they change.
+    // https://android.googlesource.com/platform/external/boringssl/+/master/src/ssl/t1_lib.c#305
+    public static final List<String> ELLIPTIC_CURVES_DEFAULT = Arrays.asList(
+            "secp256r1 (23)",
+            "secp384r1 (24)",
+            "secp521r1 (25)"
+            );
+
     private static final Set<String> PERMITTED_DEFAULT_KEY_EXCHANGE_ALGS =
             new HashSet<String>(Arrays.asList("RSA",
                                               "DHE_RSA",
@@ -1154,6 +1162,10 @@
         }
     }
 
+    public static void assertDefaultEllipticCurves(String[] curves) {
+        assertEquals(ELLIPTIC_CURVES_DEFAULT, Arrays.asList(curves));
+    }
+
     public static void assertSSLContextEnabledProtocols(String version, String[] protocols) {
         assertEquals("For protocol \"" + version + "\"",
                 Arrays.toString(SSL_CONTEXT_PROTOCOLS_ENABLED.get(version)),
diff --git a/support/src/test/java/libcore/tlswire/handshake/EllipticCurve.java b/support/src/test/java/libcore/tlswire/handshake/EllipticCurve.java
new file mode 100644
index 0000000..a409c41
--- /dev/null
+++ b/support/src/test/java/libcore/tlswire/handshake/EllipticCurve.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.tlswire.handshake;
+
+/**
+ * {@code EllipticCurve} enum from RFC 4492 section 5.1.1. Curves are assigned
+ * via the
+ * <a href="https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8">IANA registry</a>.
+ */
+public enum EllipticCurve {
+    SECT163K1(1, "sect163k1"),
+    SECT163R1(2, "sect163r1"),
+    SECT163R2(3, "sect163r2"),
+    SECT193R1(4, "sect193r1"),
+    SECT193R2(5, "sect193r2"),
+    SECT233K1(6, "sect233k1"),
+    SECT233R1(7, "sect233r1"),
+    SECT239K1(8, "sect239k1"),
+    SECT283K1(9, "sect283k1"),
+    SECT283R1(10, "sect283r1"),
+    SECT409K1(11, "sect409k1"),
+    SECT409R1(12, "sect409r1"),
+    SECT571K1(13, "sect571k1"),
+    SECT571R1(14, "sect571r1"),
+    SECP160K1(15, "secp160k1"),
+    SECP160R1(16, "secp160r1"),
+    SECP160R2(17, "secp160r2"),
+    SECP192K1(18, "secp192k1"),
+    SECP192R1(19, "secp192r1"),
+    SECP224K1(20, "secp224k1"),
+    SECP256K1(22, "secp256k1"),
+    SECP256R1(23, "secp256r1"),
+    SECP384R1(24, "secp384r1"),
+    SECP521R1(25, "secp521r1"),
+    BRAINPOOLP256R1(26, "brainpoolP256r1"),
+    BRAINPOOLP384R1(27, "brainpoolP384r1"),
+    BRAINPOOLP521R1(28, "brainpoolP521r1"),
+    X25519(29, "x25519"),
+    X448(30, "x448"),
+    ARBITRARY_PRIME(0xFF01, "arbitrary_explicit_prime_curves"),
+    ARBITRARY_CHAR2(0xFF02, "arbitrary_explicit_char2_curves");
+
+    public final int identifier;
+    public final String name;
+
+    private EllipticCurve(int identifier, String name) {
+        this.identifier = identifier;
+        this.name = name;
+    }
+
+    public static EllipticCurve fromIdentifier(int identifier) {
+        for (EllipticCurve curve : values()) {
+            if (curve.identifier == identifier) {
+                return curve;
+            }
+        }
+        throw new AssertionError("Unknown curve identifier " + identifier);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(name);
+        sb.append(" (");
+        sb.append(identifier);
+        sb.append(')');
+        return sb.toString();
+    }
+}
diff --git a/support/src/test/java/libcore/tlswire/handshake/EllipticCurvesHelloExtension.java b/support/src/test/java/libcore/tlswire/handshake/EllipticCurvesHelloExtension.java
new file mode 100644
index 0000000..19749a3
--- /dev/null
+++ b/support/src/test/java/libcore/tlswire/handshake/EllipticCurvesHelloExtension.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.tlswire.handshake;
+
+import libcore.tlswire.util.IoUtils;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * {@code elliptic_curves} {@link HelloExtension} from RFC 4492 section 5.1.1.
+ */
+public class EllipticCurvesHelloExtension extends HelloExtension {
+    public List<EllipticCurve> supported;
+    public boolean wellFormed;
+
+    @Override
+    protected void parseData() throws IOException {
+        byte[] ellipticCurvesListBytes = IoUtils.readTlsVariableLengthByteVector(
+                new DataInputStream(new ByteArrayInputStream(data)), 0xffff);
+        ByteArrayInputStream ellipticCurvesListIn = new ByteArrayInputStream(ellipticCurvesListBytes);
+        DataInputStream in = new DataInputStream(ellipticCurvesListIn);
+        wellFormed = (ellipticCurvesListIn.available() % 2) == 0;
+        supported = new ArrayList<EllipticCurve>(ellipticCurvesListIn.available() / 2);
+        while (ellipticCurvesListIn.available() >= 2) {
+            int curve_id = in.readUnsignedShort();
+            supported.add(EllipticCurve.fromIdentifier(curve_id));
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("HelloExtension{type: elliptic_curves, wellFormed: ");
+        sb.append(wellFormed);
+        sb.append(", supported: ");
+        sb.append(supported);
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git a/support/src/test/java/libcore/tlswire/handshake/HelloExtension.java b/support/src/test/java/libcore/tlswire/handshake/HelloExtension.java
index a648cdf..2a77687 100644
--- a/support/src/test/java/libcore/tlswire/handshake/HelloExtension.java
+++ b/support/src/test/java/libcore/tlswire/handshake/HelloExtension.java
@@ -29,6 +29,7 @@
 public class HelloExtension {
 
     public static final int TYPE_SERVER_NAME = 0;
+    public static final int TYPE_ELLIPTIC_CURVES = 10;
     public static final int TYPE_PADDING = 21;
     public static final int TYPE_SESSION_TICKET = 35;
     public static final int TYPE_RENEGOTIATION_INFO = 65281;
@@ -45,7 +46,7 @@
         TYPE_TO_NAME.put(7, "client_authz");
         TYPE_TO_NAME.put(8, "server_authz");
         TYPE_TO_NAME.put(9, "cert_type");
-        TYPE_TO_NAME.put(10, "elliptic_curves");
+        TYPE_TO_NAME.put(TYPE_ELLIPTIC_CURVES, "elliptic_curves");
         TYPE_TO_NAME.put(11, "ec_point_formats");
         TYPE_TO_NAME.put(12, "srp");
         TYPE_TO_NAME.put(13, "signature_algorithms");
@@ -75,6 +76,9 @@
             case TYPE_SERVER_NAME:
                 result = new ServerNameHelloExtension();
                 break;
+            case TYPE_ELLIPTIC_CURVES:
+                result = new EllipticCurvesHelloExtension();
+                break;
             default:
                 result = new HelloExtension();
                 break;