changeset 2918:33cc629889bd

Merge
author chegar
date Fri, 08 Oct 2010 11:27:55 +0100
parents efa8f714fffb 0f510337dadb
children a50828844ccc
files src/share/classes/com/sun/jndi/dns/DnsContextFactory.java src/share/classes/java/lang/Thread.java src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java src/share/native/sun/awt/image/BufImgSurfaceData.c src/share/native/sun/java2d/cmm/lcms/LCMS.c src/share/native/sun/java2d/cmm/lcms/cmsxform.c
diffstat 39 files changed, 1601 insertions(+), 454 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java	Fri Oct 08 11:27:55 2010 +0100
@@ -54,6 +54,7 @@
 public class DnsContextFactory implements InitialContextFactory {
 
     private static final String DEFAULT_URL = "dns:";
+    private static final int DEFAULT_PORT = 53;
 
 
     public Context getInitialContext(Hashtable<?,?> env) throws NamingException {
@@ -89,7 +90,9 @@
      * Public for use by product test suite.
      */
     public static boolean platformServersAvailable() {
-        return !ResolverConfiguration.open().nameservers().isEmpty();
+        return !filterNameServers(
+                    ResolverConfiguration.open().nameservers(), true
+                ).isEmpty();
     }
 
     private static Context urlToContext(String url, Hashtable env)
@@ -142,8 +145,8 @@
                 // No server or port given, so look to underlying platform.
                 // ResolverConfiguration does some limited caching, so the
                 // following is reasonably efficient even if called rapid-fire.
-                List<String> platformServers =
-                    ResolverConfiguration.open().nameservers();
+                List<String> platformServers = filterNameServers(
+                    ResolverConfiguration.open().nameservers(), false);
                 if (!platformServers.isEmpty()) {
                     servers.addAll(platformServers);
                     continue;  // on to next URL (if any, which is unlikely)
@@ -213,4 +216,44 @@
         String url = (String) env.get(Context.PROVIDER_URL);
         return ((url != null) ? url : DEFAULT_URL);
     }
+
+    /**
+     * Removes any DNS server that's not permitted to access
+     * @param input the input server[:port] list, must not be null
+     * @param oneIsEnough return output once there exists one ok
+     * @return the filtered list, all non-permitted input removed
+     */
+    private static List filterNameServers(List input, boolean oneIsEnough) {
+        SecurityManager security = System.getSecurityManager();
+        if (security == null || input == null || input.isEmpty()) {
+            return input;
+        } else {
+            List output = new ArrayList();
+            for (Object o: input) {
+                if (o instanceof String) {
+                    String platformServer = (String)o;
+                    int colon = platformServer.indexOf(':',
+                            platformServer.indexOf(']') + 1);
+
+                    int p = (colon < 0)
+                        ? DEFAULT_PORT
+                        : Integer.parseInt(
+                            platformServer.substring(colon + 1));
+                    String s = (colon < 0)
+                        ? platformServer
+                        : platformServer.substring(0, colon);
+                    try {
+                        security.checkConnect(s, p);
+                        output.add(platformServer);
+                        if (oneIsEnough) {
+                            return output;
+                        }
+                    } catch (SecurityException se) {
+                        continue;
+                    }
+                }
+            }
+            return output;
+        }
+    }
 }
--- a/src/share/classes/java/awt/image/IndexColorModel.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/java/awt/image/IndexColorModel.java	Fri Oct 08 11:27:55 2010 +0100
@@ -129,6 +129,8 @@
     private boolean allgrayopaque;
     private BigInteger validBits;
 
+    private sun.awt.image.BufImgSurfaceData.ICMColorData colorData = null;
+
     private static int[] opaqueBits = {8, 8, 8};
     private static int[] alphaBits = {8, 8, 8, 8};
 
@@ -1511,7 +1513,6 @@
      * longer referenced.
      */
     public void finalize() {
-        sun.awt.image.BufImgSurfaceData.freeNativeICMData(this);
     }
 
     /**
--- a/src/share/classes/java/net/HttpURLConnection.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/java/net/HttpURLConnection.java	Fri Oct 08 11:27:55 2010 +0100
@@ -399,6 +399,8 @@
      * @param method the HTTP method
      * @exception ProtocolException if the method cannot be reset or if
      *              the requested method isn't valid for HTTP.
+     * @exception SecurityException if a security manager is set and the
+     *              "allowHttpTrace" NetPermission is not granted.
      * @see #getRequestMethod()
      */
     public void setRequestMethod(String method) throws ProtocolException {
@@ -412,6 +414,12 @@
 
         for (int i = 0; i < methods.length; i++) {
             if (methods[i].equals(method)) {
+                if (method.equals("TRACE")) {
+                    SecurityManager s = System.getSecurityManager();
+                    if (s != null) {
+                        s.checkPermission(new NetPermission("allowHttpTrace"));
+                    }
+                }
                 this.method = method;
                 return;
             }
--- a/src/share/classes/java/net/NetPermission.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/java/net/NetPermission.java	Fri Oct 08 11:27:55 2010 +0100
@@ -54,44 +54,23 @@
  * <th>What the Permission Allows</th>
  * <th>Risks of Allowing this Permission</th>
  * </tr>
+ * <tr>
+ *   <td>allowHttpTrace</td>
+ *   <td>The ability to use the HTTP TRACE method in HttpURLConnection.</td>
+ *   <td>Malicious code using HTTP TRACE could get access to security sensitive
+ *   information in the HTTP headers (such as cookies) that it might not
+ *   otherwise have access to.</td>
+ *   </tr>
  *
  * <tr>
- *   <td>setDefaultAuthenticator</td>
- *   <td>The ability to set the
- * way authentication information is retrieved when
- * a proxy or HTTP server asks for authentication</td>
- *   <td>Malicious
- * code can set an authenticator that monitors and steals user
- * authentication input as it retrieves the input from the user.</td>
- * </tr>
- *
- * <tr>
- *   <td>requestPasswordAuthentication</td>
- *   <td>The ability
- * to ask the authenticator registered with the system for
- * a password</td>
- *   <td>Malicious code may steal this password.</td>
- * </tr>
- *
- * <tr>
- *   <td>specifyStreamHandler</td>
- *   <td>The ability
- * to specify a stream handler when constructing a URL</td>
- *   <td>Malicious code may create a URL with resources that it would
-normally not have access to (like file:/foo/fum/), specifying a
-stream handler that gets the actual bytes from someplace it does
-have access to. Thus it might be able to trick the system into
-creating a ProtectionDomain/CodeSource for a class even though
-that class really didn't come from that location.</td>
- * </tr>
- *
- * <tr>
- *   <td>setProxySelector</td>
- *   <td>The ability to set the proxy selector used to make decisions
- *   on which proxies to use when making network connections.</td>
- *   <td>Malicious code can set a ProxySelector that directs network
- *   traffic to an arbitrary network host.</td>
- * </tr>
+ *   <td>getCookieHandler</td>
+ *   <td>The ability to get the cookie handler that processes highly
+ *   security sensitive cookie information for an Http session.</td>
+ *   <td>Malicious code can get a cookie handler to obtain access to
+ *   highly security sensitive cookie information. Some web servers
+ *   use cookies to save user private information such as access
+ *   control information, or to track user browsing habit.</td>
+ *   </tr>
  *
  * <tr>
  *   <td>getProxySelector</td>
@@ -103,6 +82,22 @@
  * </tr>
  *
  * <tr>
+ *   <td>getResponseCache</td>
+ *   <td>The ability to get the response cache that provides
+ *   access to a local response cache.</td>
+ *   <td>Malicious code getting access to the local response cache
+ *   could access security sensitive information.</td>
+ *   </tr>
+ *
+ * <tr>
+ *   <td>requestPasswordAuthentication</td>
+ *   <td>The ability
+ * to ask the authenticator registered with the system for
+ * a password</td>
+ *   <td>Malicious code may steal this password.</td>
+ * </tr>
+ *
+ * <tr>
  *   <td>setCookieHandler</td>
  *   <td>The ability to set the cookie handler that processes highly
  *   security sensitive cookie information for an Http session.</td>
@@ -113,14 +108,22 @@
  *   </tr>
  *
  * <tr>
- *   <td>getCookieHandler</td>
- *   <td>The ability to get the cookie handler that processes highly
- *   security sensitive cookie information for an Http session.</td>
- *   <td>Malicious code can get a cookie handler to obtain access to
- *   highly security sensitive cookie information. Some web servers
- *   use cookies to save user private information such as access
- *   control information, or to track user browsing habit.</td>
- *   </tr>
+ *   <td>setDefaultAuthenticator</td>
+ *   <td>The ability to set the
+ * way authentication information is retrieved when
+ * a proxy or HTTP server asks for authentication</td>
+ *   <td>Malicious
+ * code can set an authenticator that monitors and steals user
+ * authentication input as it retrieves the input from the user.</td>
+ * </tr>
+ *
+ * <tr>
+ *   <td>setProxySelector</td>
+ *   <td>The ability to set the proxy selector used to make decisions
+ *   on which proxies to use when making network connections.</td>
+ *   <td>Malicious code can set a ProxySelector that directs network
+ *   traffic to an arbitrary network host.</td>
+ * </tr>
  *
  * <tr>
  *   <td>setResponseCache</td>
@@ -132,13 +135,16 @@
  *   </tr>
  *
  * <tr>
- *   <td>getResponseCache</td>
- *   <td>The ability to get the response cache that provides
- *   access to a local response cache.</td>
- *   <td>Malicious code getting access to the local response cache
- *   could access security sensitive information.</td>
- *   </tr>
- *
+ *   <td>specifyStreamHandler</td>
+ *   <td>The ability
+ * to specify a stream handler when constructing a URL</td>
+ *   <td>Malicious code may create a URL with resources that it would
+normally not have access to (like file:/foo/fum/), specifying a
+stream handler that gets the actual bytes from someplace it does
+have access to. Thus it might be able to trick the system into
+creating a ProtectionDomain/CodeSource for a class even though
+that class really didn't come from that location.</td>
+ * </tr>
  * </table>
  *
  * @see java.security.BasicPermission
--- a/src/share/classes/java/net/NetworkInterface.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/java/net/NetworkInterface.java	Fri Oct 08 11:27:55 2010 +0100
@@ -86,7 +86,9 @@
      * If there is a security manager, its <code>checkConnect</code>
      * method is called for each InetAddress. Only InetAddresses where
      * the <code>checkConnect</code> doesn't throw a SecurityException
-     * will be returned in the Enumeration.
+     * will be returned in the Enumeration. However, if the caller has the
+     * {@link NetPermission}("getNetworkInformation") permission, then all
+     * InetAddresses are returned.
      * @return an Enumeration object with all or a subset of the InetAddresses
      * bound to this network interface
      */
@@ -99,11 +101,19 @@
 
             checkedAddresses() {
                 local_addrs = new InetAddress[addrs.length];
+                boolean trusted = true;
 
                 SecurityManager sec = System.getSecurityManager();
+                if (sec != null) {
+                    try {
+                        sec.checkPermission(new NetPermission("getNetworkInformation"));
+                    } catch (SecurityException e) {
+                        trusted = false;
+                    }
+                }
                 for (int j=0; j<addrs.length; j++) {
                     try {
-                        if (sec != null) {
+                        if (sec != null && !trusted) {
                             sec.checkConnect(addrs[j].getHostAddress(), -1);
                         }
                         local_addrs[count++] = addrs[j];
@@ -402,13 +412,29 @@
     /**
      * Returns the hardware address (usually MAC) of the interface if it
      * has one and if it can be accessed given the current privileges.
+     * If a security manager is set, then the caller must have
+     * the permission {@link NetPermission}("getNetworkInformation").
      *
-     * @return  a byte array containing the address or <code>null</code> if
-     *          the address doesn't exist or is not accessible.
+     * @return  a byte array containing the address, or <code>null</code> if
+     *          the address doesn't exist, is not accessible or a security
+     *          manager is set and the caller does not have the permission
+     *          NetPermission("getNetworkInformation")
+     *
      * @exception       SocketException if an I/O error occurs.
      * @since 1.6
      */
     public byte[] getHardwareAddress() throws SocketException {
+        SecurityManager sec = System.getSecurityManager();
+        if (sec != null) {
+            try {
+                sec.checkPermission(new NetPermission("getNetworkInformation"));
+            } catch (SecurityException e) {
+                if (!getInetAddresses().hasMoreElements()) {
+                    // don't have connect permission to any local address
+                    return null;
+                }
+            }
+        }
         for (InetAddress addr : addrs) {
             if (addr instanceof Inet4Address) {
                 return getMacAddr0(((Inet4Address)addr).getAddress(), name, index);
@@ -523,11 +549,10 @@
     }
 
     public int hashCode() {
-        int count = 0;
-        if (addrs != null) {
-            for (int i = 0; i < addrs.length; i++) {
-                count += addrs[i].hashCode();
-            }
+        int count = name == null? 0: name.hashCode();
+        Enumeration<InetAddress> addrs = getInetAddresses();
+        while (addrs.hasMoreElements()) {
+            count += addrs.nextElement().hashCode();
         }
         return count;
     }
--- a/src/share/classes/javax/swing/UIDefaults.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/javax/swing/UIDefaults.java	Fri Oct 08 11:27:55 2010 +0100
@@ -52,6 +52,7 @@
 import java.security.PrivilegedAction;
 
 import sun.reflect.misc.MethodUtil;
+import sun.reflect.misc.ReflectUtil;
 import sun.util.CoreResourceBundleControl;
 
 /**
@@ -1078,6 +1079,9 @@
             // In order to pick up the security policy in effect at the
             // time of creation we use a doPrivileged with the
             // AccessControlContext that was in place when this was created.
+            if (acc == null && System.getSecurityManager() != null) {
+                throw new SecurityException("null AccessControlContext");
+            }
             return AccessController.doPrivileged(new PrivilegedAction<Object>() {
                 public Object run() {
                     try {
@@ -1093,7 +1097,9 @@
                                 cl = ClassLoader.getSystemClassLoader();
                             }
                         }
+                        ReflectUtil.checkPackageAccess(className);
                         c = Class.forName(className, true, (ClassLoader)cl);
+                        checkAccess(c.getModifiers());
                         if (methodName != null) {
                             Class[] types = getClassArray(args);
                             Method m = c.getMethod(methodName, types);
@@ -1101,6 +1107,7 @@
                         } else {
                             Class[] types = getClassArray(args);
                             Constructor constructor = c.getConstructor(types);
+                            checkAccess(constructor.getModifiers());
                             return constructor.newInstance(args);
                         }
                     } catch(Exception e) {
@@ -1115,6 +1122,13 @@
             }, acc);
         }
 
+        private void checkAccess(int modifiers) {
+            if(System.getSecurityManager() != null &&
+                    !Modifier.isPublic(modifiers)) {
+                throw new SecurityException("Resource is not accessible");
+            }
+        }
+
         /*
          * Coerce the array of class types provided into one which
          * looks the way the Reflection APIs expect.  This is done
--- a/src/share/classes/javax/swing/text/html/HTMLEditorKit.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/javax/swing/text/html/HTMLEditorKit.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -24,6 +24,8 @@
  */
 package javax.swing.text.html;
 
+import sun.awt.AppContext;
+
 import java.lang.reflect.Method;
 import java.awt.*;
 import java.awt.event.*;
@@ -369,7 +371,11 @@
      * if desired.
      */
     public void setStyleSheet(StyleSheet s) {
-        defaultStyles = s;
+        if (s == null) {
+            AppContext.getAppContext().remove(DEFAULT_STYLES_KEY);
+        } else {
+            AppContext.getAppContext().put(DEFAULT_STYLES_KEY, s);
+        }
     }
 
     /**
@@ -379,8 +385,12 @@
      * instances.
      */
     public StyleSheet getStyleSheet() {
+        AppContext appContext = AppContext.getAppContext();
+        StyleSheet defaultStyles = (StyleSheet) appContext.get(DEFAULT_STYLES_KEY);
+
         if (defaultStyles == null) {
             defaultStyles = new StyleSheet();
+            appContext.put(DEFAULT_STYLES_KEY, defaultStyles);
             try {
                 InputStream is = HTMLEditorKit.getResourceAsStream(DEFAULT_CSS);
                 Reader r = new BufferedReader(
@@ -620,7 +630,7 @@
     private static final ViewFactory defaultFactory = new HTMLFactory();
 
     MutableAttributeSet input;
-    private static StyleSheet defaultStyles = null;
+    private static final Object DEFAULT_STYLES_KEY = new Object();
     private LinkController linkHandler = new LinkController();
     private static Parser defaultParser = null;
     private Cursor defaultCursor = DefaultCursor;
--- a/src/share/classes/javax/swing/text/html/parser/DTD.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/javax/swing/text/html/parser/DTD.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -25,6 +25,8 @@
 
 package javax.swing.text.html.parser;
 
+import sun.awt.AppContext;
+
 import java.io.PrintStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -314,13 +316,14 @@
     }
 
     /**
-     * The hashtable of DTDs.
+     * The hashtable key of DTDs in AppContext.
      */
-    static Hashtable<String, DTD> dtdHash = new Hashtable<String, DTD>();
+    private static final Object DTD_HASH_KEY = new Object();
 
-  public static void putDTDHash(String name, DTD dtd) {
-    dtdHash.put(name, dtd);
-  }
+    public static void putDTDHash(String name, DTD dtd) {
+        getDtdHash().put(name, dtd);
+    }
+
     /**
      * Returns a DTD with the specified <code>name</code>.  If
      * a DTD with that name doesn't exist, one is created
@@ -332,13 +335,27 @@
      */
     public static DTD getDTD(String name) throws IOException {
         name = name.toLowerCase();
-        DTD dtd = dtdHash.get(name);
+        DTD dtd = getDtdHash().get(name);
         if (dtd == null)
           dtd = new DTD(name);
 
         return dtd;
     }
 
+    private static Hashtable<String, DTD> getDtdHash() {
+        AppContext appContext = AppContext.getAppContext();
+
+        Hashtable<String, DTD> result = (Hashtable<String, DTD>) appContext.get(DTD_HASH_KEY);
+
+        if (result == null) {
+            result = new Hashtable<String, DTD>();
+
+            appContext.put(DTD_HASH_KEY, result);
+        }
+
+        return result;
+    }
+
     /**
      * Recreates a DTD from an archived format.
      * @param in  the <code>DataInputStream</code> to read from
--- a/src/share/classes/javax/swing/text/html/parser/ParserDelegator.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/javax/swing/text/html/parser/ParserDelegator.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -25,6 +25,8 @@
 
 package javax.swing.text.html.parser;
 
+import sun.awt.AppContext;
+
 import javax.swing.text.html.HTMLEditorKit;
 import java.io.BufferedInputStream;
 import java.io.IOException;
@@ -33,7 +35,6 @@
 import java.io.ObjectInputStream;
 import java.io.Reader;
 import java.io.Serializable;
-import java.lang.reflect.Method;
 
 /**
  * Responsible for starting up a new DocumentParser
@@ -45,9 +46,13 @@
 
 public class ParserDelegator extends HTMLEditorKit.Parser implements Serializable {
 
-    private static DTD dtd = null;
+    private static final Object DTD_KEY = new Object();
 
     protected static synchronized void setDefaultDTD() {
+        AppContext appContext = AppContext.getAppContext();
+
+        DTD dtd = (DTD) appContext.get(DTD_KEY);
+
         if (dtd == null) {
             DTD _dtd = null;
             // (PENDING) Hate having to hard code!
@@ -59,6 +64,8 @@
                 System.out.println("Throw an exception: could not get default dtd: " + nm);
             }
             dtd = createDTD(_dtd, nm);
+
+            appContext.put(DTD_KEY, dtd);
         }
     }
 
@@ -81,13 +88,11 @@
 
 
     public ParserDelegator() {
-        if (dtd == null) {
-            setDefaultDTD();
-        }
+        setDefaultDTD();
     }
 
     public void parse(Reader r, HTMLEditorKit.ParserCallback cb, boolean ignoreCharSet) throws IOException {
-        new DocumentParser(dtd).parse(r, cb, ignoreCharSet);
+        new DocumentParser((DTD) AppContext.getAppContext().get(DTD_KEY)).parse(r, cb, ignoreCharSet);
     }
 
     /**
@@ -113,8 +118,6 @@
     private void readObject(ObjectInputStream s)
         throws ClassNotFoundException, IOException {
         s.defaultReadObject();
-        if (dtd == null) {
-            setDefaultDTD();
-        }
+        setDefaultDTD();
     }
 }
--- a/src/share/classes/sun/awt/image/BufImgSurfaceData.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/sun/awt/image/BufImgSurfaceData.java	Fri Oct 08 11:27:55 2010 +0100
@@ -49,7 +49,7 @@
     private BufferedImageGraphicsConfig graphicsConfig;
     RenderLoops solidloops;
 
-    private static native void initIDs(Class ICM);
+    private static native void initIDs(Class ICM, Class ICMColorData);
 
     private static final int DCM_RGBX_RED_MASK   = 0xff000000;
     private static final int DCM_RGBX_GREEN_MASK = 0x00ff0000;
@@ -67,7 +67,7 @@
     private static final int DCM_ARGBBM_BLUE_MASK  = 0x000000ff;
 
     static {
-        initIDs(IndexColorModel.class);
+        initIDs(IndexColorModel.class, ICMColorData.class);
     }
 
     public static SurfaceData createData(BufferedImage bufImg) {
@@ -403,7 +403,7 @@
         // their pixels are immediately retrievable anyway.
     }
 
-    public static native void freeNativeICMData(IndexColorModel icm);
+    private static native void freeNativeICMData(long pData);
 
     /**
      * Returns destination Image associated with this SurfaceData.
@@ -411,4 +411,19 @@
     public Object getDestination() {
         return bufImg;
     }
+
+    public static final class ICMColorData {
+        private long pData = 0L;
+
+        private ICMColorData(long pData) {
+            this.pData = pData;
+        }
+
+        public void finalize() {
+            if (pData != 0L) {
+                BufImgSurfaceData.freeNativeICMData(pData);
+                pData = 0L;
+            }
+        }
+    }
 }
--- a/src/share/classes/sun/net/www/MessageHeader.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/sun/net/www/MessageHeader.java	Fri Oct 08 11:27:55 2010 +0100
@@ -196,6 +196,10 @@
     }
 
     public synchronized Map<String, List<String>> getHeaders(String[] excludeList) {
+        return filterAndAddHeaders(excludeList, null);
+    }
+
+    public synchronized Map<String, List<String>> filterAndAddHeaders(String[] excludeList, Map<String, List<String>>  include) {
         boolean skipIt = false;
         Map<String, List<String>> m = new HashMap<String, List<String>>();
         for (int i = nkeys; --i >= 0;) {
@@ -223,6 +227,19 @@
             }
         }
 
+        if (include != null) {
+            Iterator entries = include.entrySet().iterator();
+            while (entries.hasNext()) {
+                Map.Entry entry = (Map.Entry)entries.next();
+                List l = (List)m.get(entry.getKey());
+                if (l == null) {
+                    l = new ArrayList();
+                    m.put((String)entry.getKey(), l);
+                }
+                l.add(entry.getValue());
+            }
+        }
+
         for (String key : m.keySet()) {
             m.put(key, Collections.unmodifiableList(m.get(key)));
         }
--- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Fri Oct 08 11:27:55 2010 +0100
@@ -51,6 +51,9 @@
 import java.util.Locale;
 import java.util.StringTokenizer;
 import java.util.Iterator;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.Set;
 import sun.net.*;
 import sun.net.www.*;
 import sun.net.www.http.HttpClient;
@@ -140,6 +143,54 @@
     */
     private static int bufSize4ES = 0;
 
+    /*
+     * Restrict setting of request headers through the public api
+     * consistent with JavaScript XMLHttpRequest2 with a few
+     * exceptions. Disallowed headers are silently ignored for
+     * backwards compatibility reasons rather than throwing a
+     * SecurityException. For example, some applets set the
+     * Host header since old JREs did not implement HTTP 1.1.
+     * Additionally, any header starting with Sec- is
+     * disallowed.
+     *
+     * The following headers are allowed for historical reasons:
+     *
+     * Accept-Charset, Accept-Encoding, Cookie, Cookie2, Date,
+     * Referer, TE, User-Agent, headers beginning with Proxy-.
+     *
+     * The following headers are allowed in a limited form:
+     *
+     * Connection: close
+     *
+     * See http://www.w3.org/TR/XMLHttpRequest2.
+     */
+    private static final boolean allowRestrictedHeaders;
+    private static final Set<String> restrictedHeaderSet;
+    private static final String[] restrictedHeaders = {
+        /* Restricted by XMLHttpRequest2 */
+        //"Accept-Charset",
+        //"Accept-Encoding",
+        "Access-Control-Request-Headers",
+        "Access-Control-Request-Method",
+        "Connection", /* close is allowed */
+        "Content-Length",
+        //"Cookie",
+        //"Cookie2",
+        "Content-Transfer-Encoding",
+        //"Date",
+        //"Expect",
+        "Host",
+        "Keep-Alive",
+        "Origin",
+        // "Referer",
+        // "TE",
+        "Trailer",
+        "Transfer-Encoding",
+        "Upgrade",
+        //"User-Agent",
+        "Via"
+    };
+
     static {
         maxRedirects = java.security.AccessController.doPrivileged(
             new sun.security.action.GetIntegerAction(
@@ -178,7 +229,17 @@
             bufSize4ES = 4096; // use the default
         }
 
-
+        allowRestrictedHeaders = ((Boolean)java.security.AccessController.doPrivileged(
+                new sun.security.action.GetBooleanAction(
+                    "sun.net.http.allowRestrictedHeaders"))).booleanValue();
+        if (!allowRestrictedHeaders) {
+            restrictedHeaderSet = new HashSet<String>(restrictedHeaders.length);
+            for (int i=0; i < restrictedHeaders.length; i++) {
+                restrictedHeaderSet.add(restrictedHeaders[i].toLowerCase());
+            }
+        } else {
+            restrictedHeaderSet = null;
+        }
     }
 
     static final String httpVersion = "HTTP/1.1";
@@ -191,6 +252,15 @@
             "Proxy-Authorization",
             "Authorization"
     };
+
+    // also exclude system cookies when any might be set
+    private static final String[] EXCLUDE_HEADERS2= {
+            "Proxy-Authorization",
+            "Authorization",
+            "Cookie",
+            "Cookie2"
+    };
+
     protected HttpClient http;
     protected Handler handler;
     protected Proxy instProxy;
@@ -213,6 +283,7 @@
     /* User set Cookies */
     private boolean setUserCookies = true;
     private String userCookies = null;
+    private String userCookies2 = null;
 
     /* We only have a single static authenticator for now.
      * REMIND:  backwards compatibility with JDK 1.1.  Should be
@@ -329,6 +400,41 @@
             });
     }
 
+    private boolean isRestrictedHeader(String key, String value) {
+        if (allowRestrictedHeaders) {
+            return false;
+        }
+
+        key = key.toLowerCase();
+        if (restrictedHeaderSet.contains(key)) {
+            /*
+             * Exceptions to restricted headers:
+             *
+             * Allow "Connection: close".
+             */
+            if (key.equals("connection") && value.equalsIgnoreCase("close")) {
+                return false;
+            }
+            return true;
+        } else if (key.startsWith("sec-")) {
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * Checks the validity of http message header and whether the header
+     * is restricted and throws IllegalArgumentException if invalid or
+     * restricted.
+     */
+    private boolean isExternalMessageHeaderAllowed(String key, String value) {
+        checkMessageHeader(key, value);
+        if (!isRestrictedHeader(key, value)) {
+            return true;
+        }
+        return false;
+    }
+
     /* Logging support */
     public static PlatformLogger getHttpLogger() {
         return logger;
@@ -463,9 +569,12 @@
                         "application/x-www-form-urlencoded");
             }
 
+            boolean chunked = false;
+
             if (streaming()) {
                 if (chunkLength != -1) {
                     requests.set ("Transfer-Encoding", "chunked");
+                    chunked = true;
                 } else { /* fixed content length */
                     if (fixedContentLengthLong != -1) {
                         requests.set ("Content-Length",
@@ -485,6 +594,16 @@
                 }
             }
 
+            if (!chunked) {
+                if (requests.findValue("Transfer-Encoding") != null) {
+                    requests.remove("Transfer-Encoding");
+                    if (logger.isLoggable(PlatformLogger.WARNING)) {
+                        logger.warning(
+                            "use streaming mode for chunked encoding");
+                    }
+                }
+            }
+
             // get applicable cookies based on the uri and request headers
             // add them to the existing request headers
             setCookieHeader();
@@ -1034,15 +1153,21 @@
             // we only want to capture the user defined Cookies once, as
             // they cannot be changed by user code after we are connected,
             // only internally.
-            if (setUserCookies) {
-                int k = requests.getKey("Cookie");
-                if ( k != -1)
-                    userCookies = requests.getValue(k);
-                setUserCookies = false;
+            synchronized (this) {
+                if (setUserCookies) {
+                    int k = requests.getKey("Cookie");
+                    if (k != -1)
+                        userCookies = requests.getValue(k);
+                    k = requests.getKey("Cookie2");
+                    if (k != -1)
+                        userCookies2 = requests.getValue(k);
+                    setUserCookies = false;
+                }
             }
 
             // remove old Cookie header before setting new one.
             requests.remove("Cookie");
+            requests.remove("Cookie2");
 
             URI uri = ParseUtil.toURI(url);
             if (uri != null) {
@@ -1088,6 +1213,13 @@
                 else
                     requests.set("Cookie", userCookies);
             }
+            if (userCookies2 != null) {
+                int k;
+                if ((k = requests.getKey("Cookie2")) != -1)
+                    requests.set("Cookie2", requests.getValue(k) + ";" + userCookies2);
+                else
+                    requests.set("Cookie2", userCookies2);
+            }
 
         } // end of getting cookies
     }
@@ -2530,8 +2662,9 @@
         if (key == null)
             throw new NullPointerException ("key is null");
 
-        checkMessageHeader(key, value);
-        requests.set(key, value);
+        if (isExternalMessageHeaderAllowed(key, value)) {
+            requests.set(key, value);
+        }
     }
 
     /**
@@ -2552,8 +2685,9 @@
         if (key == null)
             throw new NullPointerException ("key is null");
 
-        checkMessageHeader(key, value);
-        requests.add(key, value);
+        if (isExternalMessageHeaderAllowed(key, value)) {
+            requests.add(key, value);
+        }
     }
 
     //
@@ -2566,13 +2700,23 @@
     }
 
     @Override
-    public String getRequestProperty (String key) {
+    public synchronized String getRequestProperty (String key) {
+        if (key == null) {
+            return null;
+        }
+
         // don't return headers containing security sensitive information
-        if (key != null) {
-            for (int i=0; i < EXCLUDE_HEADERS.length; i++) {
-                if (key.equalsIgnoreCase(EXCLUDE_HEADERS[i])) {
-                    return null;
-                }
+        for (int i=0; i < EXCLUDE_HEADERS.length; i++) {
+            if (key.equalsIgnoreCase(EXCLUDE_HEADERS[i])) {
+                return null;
+            }
+        }
+        if (!setUserCookies) {
+            if (key.equalsIgnoreCase("Cookie")) {
+                return userCookies;
+            }
+            if (key.equalsIgnoreCase("Cookie2")) {
+                return userCookies2;
             }
         }
         return requests.findValue(key);
@@ -2591,12 +2735,29 @@
      * @since 1.4
      */
     @Override
-    public Map<String, List<String>> getRequestProperties() {
+    public synchronized Map<String, List<String>> getRequestProperties() {
         if (connected)
             throw new IllegalStateException("Already connected");
 
         // exclude headers containing security-sensitive info
-        return requests.getHeaders(EXCLUDE_HEADERS);
+        if (setUserCookies) {
+            return requests.getHeaders(EXCLUDE_HEADERS);
+        }
+        /*
+         * The cookies in the requests message headers may have
+         * been modified. Use the saved user cookies instead.
+         */
+        Map userCookiesMap = null;
+        if (userCookies != null || userCookies2 != null) {
+            userCookiesMap = new HashMap();
+            if (userCookies != null) {
+                userCookiesMap.put("Cookie", userCookies);
+            }
+            if (userCookies2 != null) {
+                userCookiesMap.put("Cookie2", userCookies2);
+            }
+        }
+        return requests.filterAndAddHeaders(EXCLUDE_HEADERS2, userCookiesMap);
     }
 
     @Override
--- a/src/share/classes/sun/security/jgss/krb5/InitialToken.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/sun/security/jgss/krb5/InitialToken.java	Fri Oct 08 11:27:55 2010 +0100
@@ -35,7 +35,6 @@
 import java.security.NoSuchAlgorithmException;
 import java.util.Arrays;
 import sun.security.krb5.*;
-import sun.security.jgss.HttpCaller;
 import sun.security.krb5.internal.Krb5;
 
 abstract class InitialToken extends Krb5Token {
@@ -217,6 +216,12 @@
 
             int pos = 0;
 
+            if (checksum == null) {
+                GSSException ge = new GSSException(GSSException.FAILURE, -1,
+                        "No cksum in AP_REQ's authenticator");
+                ge.initCause(new KrbException(Krb5.KRB_AP_ERR_INAPP_CKSUM));
+                throw ge;
+            }
             checksumBytes = checksum.getBytes();
 
             if ((checksumBytes[0] != CHECKSUM_FIRST_BYTES[0]) ||
--- a/src/share/classes/sun/security/ssl/Alerts.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/sun/security/ssl/Alerts.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -74,7 +74,7 @@
     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_negotiation = 100;
+    static final byte           alert_no_renegotiation = 100;
 
     // from RFC 3546 (TLS Extensions)
     static final byte           alert_unsupported_extension = 110;
@@ -132,8 +132,8 @@
             return "internal_error";
         case alert_user_canceled:
             return "user_canceled";
-        case alert_no_negotiation:
-            return "no_negotiation";
+        case alert_no_renegotiation:
+            return "no_renegotiation";
         case alert_unsupported_extension:
             return "unsupported_extension";
         case alert_certificate_unobtainable:
@@ -203,7 +203,7 @@
         case alert_protocol_version:
         case alert_internal_error:
         case alert_user_canceled:
-        case alert_no_negotiation:
+        case alert_no_renegotiation:
         default:
             e = new SSLException(reason);
             break;
--- a/src/share/classes/sun/security/ssl/CipherSuite.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/sun/security/ssl/CipherSuite.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -126,6 +126,8 @@
             macAlg = M_SHA;
         } 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);
@@ -160,6 +162,10 @@
         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
@@ -268,7 +274,10 @@
 
         // Kerberos cipher suites
         K_KRB5       ("KRB5", true),
-        K_KRB5_EXPORT("KRB5_EXPORT", 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;
@@ -352,7 +361,8 @@
             this.exportable = true;
         }
 
-        BulkCipher(String transformation, int keySize, int ivSize, boolean allowed) {
+        BulkCipher(String transformation, int keySize,
+                int ivSize, boolean allowed) {
             this.transformation = transformation;
             this.algorithm = transformation.split("/")[0];
             this.description = this.algorithm + "/" + (keySize << 3);
@@ -370,7 +380,8 @@
          *
          * @exception NoSuchAlgorithmException if anything goes wrong
          */
-        CipherBox newCipher(ProtocolVersion version, SecretKey key, IvParameterSpec iv,
+        CipherBox newCipher(ProtocolVersion version,
+                SecretKey key, IvParameterSpec iv,
                 boolean encrypt) throws NoSuchAlgorithmException {
             return CipherBox.newCipherBox(version, this, key, iv, encrypt);
         }
@@ -407,8 +418,9 @@
             if (b == null) {
                 try {
                     SecretKey key = new SecretKeySpec
-                            (new byte[cipher.expandedKeySize], cipher.algorithm);
-                    IvParameterSpec iv = new IvParameterSpec(new byte[cipher.ivSize]);
+                        (new byte[cipher.expandedKeySize], cipher.algorithm);
+                    IvParameterSpec iv =
+                        new IvParameterSpec(new byte[cipher.ivSize]);
                     cipher.newCipher(ProtocolVersion.DEFAULT, key, iv, true);
                     b = Boolean.TRUE;
                 } catch (NoSuchAlgorithmException e) {
@@ -460,18 +472,28 @@
     }
 
     // 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);
+    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);
+    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);
@@ -487,93 +509,159 @@
         // N: ciphersuites only allowed if we are not in FIPS mode
         final boolean N = (SunJSSE.isFIPS() == false);
 
-add("SSL_NULL_WITH_NULL_NULL",                0x0000,   1, K_NULL,       B_NULL,    F);
+        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.
         int p = DEFAULT_SUITES_PRIORITY * 2;
 
-add("SSL_RSA_WITH_RC4_128_MD5",              0x0004, --p, K_RSA,        B_RC4_128, N);
-add("SSL_RSA_WITH_RC4_128_SHA",              0x0005, --p, K_RSA,        B_RC4_128, N);
-add("TLS_RSA_WITH_AES_128_CBC_SHA",          0x002f, --p, K_RSA,        B_AES_128, T);
-add("TLS_RSA_WITH_AES_256_CBC_SHA",          0x0035, --p, K_RSA,        B_AES_256, T);
+        add("SSL_RSA_WITH_RC4_128_MD5",
+                              0x0004, --p, K_RSA,        B_RC4_128, N);
+        add("SSL_RSA_WITH_RC4_128_SHA",
+                              0x0005, --p, K_RSA,        B_RC4_128, N);
+        add("TLS_RSA_WITH_AES_128_CBC_SHA",
+                              0x002f, --p, K_RSA,        B_AES_128, T);
+        add("TLS_RSA_WITH_AES_256_CBC_SHA",
+                              0x0035, --p, K_RSA,        B_AES_256, T);
 
-add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA",       0xC002, --p, K_ECDH_ECDSA, B_RC4_128, N);
-add("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",   0xC004, --p, K_ECDH_ECDSA, B_AES_128, T);
-add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",   0xC005, --p, K_ECDH_ECDSA, B_AES_256, T);
-add("TLS_ECDH_RSA_WITH_RC4_128_SHA",         0xC00C, --p, K_ECDH_RSA,   B_RC4_128, N);
-add("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",     0xC00E, --p, K_ECDH_RSA,   B_AES_128, T);
-add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",     0xC00F, --p, K_ECDH_RSA,   B_AES_256, T);
+        add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
+                              0xC002, --p, K_ECDH_ECDSA, B_RC4_128, N);
+        add("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
+                              0xC004, --p, K_ECDH_ECDSA, B_AES_128, T);
+        add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
+                              0xC005, --p, K_ECDH_ECDSA, B_AES_256, T);
+        add("TLS_ECDH_RSA_WITH_RC4_128_SHA",
+                              0xC00C, --p, K_ECDH_RSA,   B_RC4_128, N);
+        add("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
+                              0xC00E, --p, K_ECDH_RSA,   B_AES_128, T);
+        add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
+                              0xC00F, --p, K_ECDH_RSA,   B_AES_256, T);
 
-add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",      0xC007, --p, K_ECDHE_ECDSA,B_RC4_128, N);
-add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",  0xC009, --p, K_ECDHE_ECDSA,B_AES_128, T);
-add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",  0xC00A, --p, K_ECDHE_ECDSA,B_AES_256, T);
-add("TLS_ECDHE_RSA_WITH_RC4_128_SHA",        0xC011, --p, K_ECDHE_RSA,  B_RC4_128, N);
-add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",    0xC013, --p, K_ECDHE_RSA,  B_AES_128, T);
-add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",    0xC014, --p, K_ECDHE_RSA,  B_AES_256, T);
+        add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
+                              0xC007, --p, K_ECDHE_ECDSA,B_RC4_128, N);
+        add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
+                              0xC009, --p, K_ECDHE_ECDSA,B_AES_128, T);
+        add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
+                              0xC00A, --p, K_ECDHE_ECDSA,B_AES_256, T);
+        add("TLS_ECDHE_RSA_WITH_RC4_128_SHA",
+                              0xC011, --p, K_ECDHE_RSA,  B_RC4_128, N);
+        add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
+                              0xC013, --p, K_ECDHE_RSA,  B_AES_128, T);
+        add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
+                              0xC014, --p, K_ECDHE_RSA,  B_AES_256, T);
 
-add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA",      0x0033, --p, K_DHE_RSA,    B_AES_128, 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_128_CBC_SHA",      0x0032, --p, K_DHE_DSS,    B_AES_128, T);
-add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA",      0x0038, --p, K_DHE_DSS,    B_AES_256, T);
+        add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
+                              0x0033, --p, K_DHE_RSA,    B_AES_128, 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_128_CBC_SHA",
+                              0x0032, --p, K_DHE_DSS,    B_AES_128, T);
+        add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
+                              0x0038, --p, K_DHE_DSS,    B_AES_256, 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("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_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_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("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_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_DES_CBC_SHA",              0x0009, --p, K_RSA,        B_DES,     N);
-add("SSL_DHE_RSA_WITH_DES_CBC_SHA",          0x0015, --p, K_DHE_RSA,    B_DES,     N);
-add("SSL_DHE_DSS_WITH_DES_CBC_SHA",          0x0012, --p, K_DHE_DSS,    B_DES,     N);
-add("SSL_RSA_EXPORT_WITH_RC4_40_MD5",        0x0003, --p, K_RSA_EXPORT, B_RC4_40,  N);
-add("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",     0x0008, --p, K_RSA_EXPORT, B_DES_40,  N);
-add("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x0014, --p, K_DHE_RSA,    B_DES_40,  N);
-add("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", 0x0011, --p, K_DHE_DSS,    B_DES_40,  N);
+        add("SSL_RSA_WITH_DES_CBC_SHA",
+                              0x0009, --p, K_RSA,        B_DES,     N);
+        add("SSL_DHE_RSA_WITH_DES_CBC_SHA",
+                              0x0015, --p, K_DHE_RSA,    B_DES,     N);
+        add("SSL_DHE_DSS_WITH_DES_CBC_SHA",
+                              0x0012, --p, K_DHE_DSS,    B_DES,     N);
+        add("SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+                              0x0003, --p, K_RSA_EXPORT, B_RC4_40,  N);
+        add("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+                              0x0008, --p, K_RSA_EXPORT, B_DES_40,  N);
+        add("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+                              0x0014, --p, K_DHE_RSA,    B_DES_40,  N);
+        add("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+                              0x0011, --p, K_DHE_DSS,    B_DES_40,  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.
         p = DEFAULT_SUITES_PRIORITY;
 
-// Anonymous key exchange and the NULL ciphers
-add("SSL_RSA_WITH_NULL_MD5",                 0x0001, --p, K_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_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);
+        // Anonymous key exchange and the NULL ciphers
+        add("SSL_RSA_WITH_NULL_MD5",
+                              0x0001, --p, K_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_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_DH_anon_WITH_RC4_128_MD5",          0x0018, --p, K_DH_ANON,    B_RC4_128, N);
-add("TLS_DH_anon_WITH_AES_128_CBC_SHA",      0x0034, --p, K_DH_ANON,    B_AES_128, N);
-add("TLS_DH_anon_WITH_AES_256_CBC_SHA",      0x003a, --p, K_DH_ANON,    B_AES_256, N);
-add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",     0x001b, --p, K_DH_ANON,    B_3DES,    N);
-add("SSL_DH_anon_WITH_DES_CBC_SHA",          0x001a, --p, K_DH_ANON,    B_DES,     N);
+        add("SSL_DH_anon_WITH_RC4_128_MD5",
+                              0x0018, --p, K_DH_ANON,    B_RC4_128, N);
+        add("TLS_DH_anon_WITH_AES_128_CBC_SHA",
+                              0x0034, --p, K_DH_ANON,    B_AES_128, N);
+        add("TLS_DH_anon_WITH_AES_256_CBC_SHA",
+                              0x003a, --p, K_DH_ANON,    B_AES_256, N);
+        add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",
+                              0x001b, --p, K_DH_ANON,    B_3DES,    N);
+        add("SSL_DH_anon_WITH_DES_CBC_SHA",
+                              0x001a, --p, K_DH_ANON,    B_DES,     N);
 
-add("TLS_ECDH_anon_WITH_RC4_128_SHA",        0xC016, --p, K_ECDH_ANON,  B_RC4_128, N);
-add("TLS_ECDH_anon_WITH_AES_128_CBC_SHA",    0xC018, --p, K_ECDH_ANON,  B_AES_128, T);
-add("TLS_ECDH_anon_WITH_AES_256_CBC_SHA",    0xC019, --p, K_ECDH_ANON,  B_AES_256, T);
-add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",   0xC017, --p, K_ECDH_ANON,  B_3DES,    T);
+        add("TLS_ECDH_anon_WITH_RC4_128_SHA",
+                              0xC016, --p, K_ECDH_ANON,  B_RC4_128, N);
+        add("TLS_ECDH_anon_WITH_AES_128_CBC_SHA",
+                              0xC018, --p, K_ECDH_ANON,  B_AES_128, T);
+        add("TLS_ECDH_anon_WITH_AES_256_CBC_SHA",
+                              0xC019, --p, K_ECDH_ANON,  B_AES_256, T);
+        add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
+                              0xC017, --p, K_ECDH_ANON,  B_3DES,    T);
 
-add("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",    0x0017, --p, K_DH_ANON,    B_RC4_40,  N);
-add("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", 0x0019, --p, K_DH_ANON,    B_DES_40,  N);
+        add("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
+                              0x0017, --p, K_DH_ANON,    B_RC4_40,  N);
+        add("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
+                              0x0019, --p, K_DH_ANON,    B_DES_40,  N);
 
-add("TLS_ECDH_anon_WITH_NULL_SHA",           0xC015, --p, K_ECDH_ANON,  B_NULL,    N);
+        add("TLS_ECDH_anon_WITH_NULL_SHA",
+                              0xC015, --p, K_ECDH_ANON,  B_NULL,    N);
 
-// 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);
-add("TLS_KRB5_WITH_DES_CBC_MD5",             0x0022, --p, K_KRB5,        B_DES,     N);
-add("TLS_KRB5_EXPORT_WITH_RC4_40_SHA",       0x0028, --p, K_KRB5_EXPORT, B_RC4_40,  N);
-add("TLS_KRB5_EXPORT_WITH_RC4_40_MD5",       0x002b, --p, K_KRB5_EXPORT, B_RC4_40,  N);
-add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA",   0x0026, --p, K_KRB5_EXPORT, B_DES_40,  N);
-add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5",   0x0029, --p, K_KRB5_EXPORT, B_DES_40,  N);
-
+        // 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);
+        add("TLS_KRB5_WITH_DES_CBC_MD5",
+                              0x0022, --p, K_KRB5,        B_DES,     N);
+        add("TLS_KRB5_EXPORT_WITH_RC4_40_SHA",
+                              0x0028, --p, K_KRB5_EXPORT, B_RC4_40,  N);
+        add("TLS_KRB5_EXPORT_WITH_RC4_40_MD5",
+                              0x002b, --p, K_KRB5_EXPORT, B_RC4_40,  N);
+        add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA",
+                              0x0026, --p, K_KRB5_EXPORT, B_DES_40,  N);
+        add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5",
+                              0x0029, --p, K_KRB5_EXPORT, B_DES_40,  N);
 
         // Register the names of a few additional CipherSuites.
         // Makes them show up as names instead of numbers in
@@ -618,4 +706,6 @@
     // 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);
 }
--- a/src/share/classes/sun/security/ssl/CipherSuiteList.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/sun/security/ssl/CipherSuiteList.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -51,8 +51,9 @@
     // null if not yet checked.
     private volatile Boolean containsEC;
 
-    // for use by buildAvailableCache() only
-    private CipherSuiteList(Collection<CipherSuite> cipherSuites) {
+    // for use by buildAvailableCache() and
+    // Handshaker.getKickstartMessage() only
+    CipherSuiteList(Collection<CipherSuite> cipherSuites) {
         this.cipherSuites = cipherSuites;
     }
 
@@ -221,15 +222,18 @@
         // SortedSet automatically arranges ciphersuites in default
         // preference order
         Set<CipherSuite> cipherSuites = new TreeSet<CipherSuite>();
-        Collection<CipherSuite> allowedCipherSuites = CipherSuite.allowedCipherSuites();
+        Collection<CipherSuite> allowedCipherSuites =
+                                    CipherSuite.allowedCipherSuites();
         for (CipherSuite c : allowedCipherSuites) {
             if ((c.allowed == false) || (c.priority < minPriority)) {
                 continue;
             }
+
             if (c.isAvailable()) {
                 cipherSuites.add(c);
             }
         }
+
         return new CipherSuiteList(cipherSuites);
     }
 
--- a/src/share/classes/sun/security/ssl/ClientHandshaker.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/sun/security/ssl/ClientHandshaker.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -94,16 +94,24 @@
      */
     ClientHandshaker(SSLSocketImpl socket, SSLContextImpl context,
             ProtocolList enabledProtocols,
-            ProtocolVersion activeProtocolVersion) {
-        super(socket, context, enabledProtocols, true, true);
-        this.activeProtocolVersion = activeProtocolVersion;
+            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) {
-        super(engine, context, enabledProtocols, true, true);
-        this.activeProtocolVersion = activeProtocolVersion;
+            ProtocolVersion activeProtocolVersion,
+            boolean isInitialHandshake, boolean secureRenegotiation,
+            byte[] clientVerifyData, byte[] serverVerifyData) {
+
+        super(engine, context, enabledProtocols, true, true,
+            activeProtocolVersion, isInitialHandshake, secureRenegotiation,
+            clientVerifyData, serverVerifyData);
     }
 
     /*
@@ -279,10 +287,11 @@
         // sent the "client hello" but the server's not seen it.
         //
         if (state < HandshakeMessage.ht_client_hello) {
-            if (!renegotiable) {    // renegotiation is not allowed.
+            if (!secureRenegotiation && !allowUnsafeRenegotiation) {
+                // renegotiation is not allowed.
                 if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) {
-                    // response with a no_negotiation warning,
-                    warningSE(Alerts.alert_no_negotiation);
+                    // response with a no_renegotiation warning,
+                    warningSE(Alerts.alert_no_renegotiation);
 
                     // invalidate the handshake so that the caller can
                     // dispose this object.
@@ -293,26 +302,24 @@
                     // 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,
-                            "HelloRequest followed by an unexpected  " +
-                            "handshake message");
-                    }
-
+                    // 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_negotiation alert
-                    // like TLSv1. However we cannot ignore the message
+                    // 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");
+                        "Renegotiation is not allowed");
                 }
             } else {
+                if (!secureRenegotiation) {
+                    if (debug != null && Debug.isOn("handshake")) {
+                        System.out.println(
+                            "Warning: continue with insecure renegotiation");
+                    }
+                }
                 kickstart();
             }
         }
@@ -347,6 +354,68 @@
         // 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
@@ -354,10 +423,11 @@
         //
         svr_random = mesg.svr_random;
 
-        if (isEnabled(mesg.cipherSuite) == false) {
+        if (isNegotiable(mesg.cipherSuite) == false) {
             fatalSE(Alerts.alert_illegal_parameter,
-                "Server selected disabled ciphersuite " + cipherSuite);
+                "Server selected improper ciphersuite " + cipherSuite);
         }
+
         setCipherSuite(mesg.cipherSuite);
 
         if (mesg.compression_method != 0) {
@@ -452,7 +522,8 @@
         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_EC_POINT_FORMATS)
+                    && (type != ExtensionType.EXT_RENEGOTIATION_INFO)) {
                 fatalSE(Alerts.alert_unsupported_extension,
                     "Server sent an unsupported extension: " + type);
             }
@@ -869,6 +940,13 @@
         }
 
         /*
+         * 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
@@ -921,6 +999,13 @@
         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.)
@@ -933,12 +1018,15 @@
      * Returns a ClientHello message to kickstart renegotiations
      */
     HandshakeMessage getKickstartMessage() throws SSLException {
-        ClientHello mesg = new ClientHello(sslContext.getSecureRandom(),
-                                        protocolVersion);
+        // session ID of the ClientHello message
+        SessionId sessionId = SSLSessionImpl.nullSession.getSessionId();
+
+        // a list of cipher suites sent by the client
+        CipherSuiteList cipherSuites = enabledCipherSuites;
+
+        // set the max protocol version this client is supporting.
         maxProtocolVersion = protocolVersion;
 
-        clnt_random = mesg.clnt_random;
-
         //
         // Try to resume an existing session.  This might be mandatory,
         // given certain API options.
@@ -962,9 +1050,9 @@
         if (session != null) {
             CipherSuite sessionSuite = session.getSuite();
             ProtocolVersion sessionVersion = session.getProtocolVersion();
-            if (isEnabled(sessionSuite) == false) {
+            if (isNegotiable(sessionSuite) == false) {
                 if (debug != null && Debug.isOn("session")) {
-                    System.out.println("%% can't resume, cipher disabled");
+                    System.out.println("%% can't resume, unavailable cipher");
                 }
                 session = null;
             }
@@ -984,9 +1072,8 @@
                             + " from port " + getLocalPortSE());
                     }
                 }
-                mesg.sessionId = session.getSessionId();
 
-                mesg.protocolVersion = sessionVersion;
+                sessionId = session.getSessionId();
                 maxProtocolVersion = sessionVersion;
 
                 // Update SSL version number in underlying SSL socket and
@@ -995,33 +1082,78 @@
                 setVersion(sessionVersion);
             }
 
-            //
-            // don't say much beyond the obvious if we _must_ resume.
-            //
+            /*
+             * Force use of the previous session ciphersuite, and
+             * add the SCSV if enabled.
+             */
             if (!enableNewSession) {
                 if (session == null) {
                     throw new SSLException(
                         "Can't reuse existing SSL client session");
                 }
-                mesg.setCipherSuites(new CipherSuiteList(sessionSuite));
-                return mesg;
-            }
-        }
-        if (session == null) {
-            if (enableNewSession) {
-                mesg.sessionId = SSLSessionImpl.nullSession.getSessionId();
-            } else {
-                throw new SSLException("No existing session to resume.");
+
+                Collection<CipherSuite> cipherList =
+                                                new ArrayList<CipherSuite>(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);
             }
         }
 
-        //
-        // All we have left to do is fill out the cipher suites.
-        // (If this changes, change the 'return' above!)
-        //
-        mesg.setCipherSuites(enabledCipherSuites);
+        if (session == null && !enableNewSession) {
+            throw new SSLException("No existing session to resume");
+        }
 
-        return mesg;
+        // exclude SCSV for secure renegotiation
+        if (secureRenegotiation && cipherSuites.contains(CipherSuite.C_SCSV)) {
+            Collection<CipherSuite> cipherList =
+                        new ArrayList<CipherSuite>(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 SSLException("No negotiable cipher suite");
+        }
+
+        // create the ClientHello message
+        ClientHello clientHelloMessage = new ClientHello(
+                sslContext.getSecureRandom(), maxProtocolVersion,
+                sessionId, cipherSuites);
+
+        // 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;
     }
 
     /*
--- a/src/share/classes/sun/security/ssl/HandshakeMessage.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/sun/security/ssl/HandshakeMessage.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -172,9 +172,7 @@
  * 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
-{
+static final class HelloRequest extends HandshakeMessage {
     int messageType() { return ht_hello_request; }
 
     HelloRequest() { }
@@ -210,10 +208,7 @@
  * 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
-{
-    int messageType() { return ht_client_hello; }
+static final class ClientHello extends HandshakeMessage {
 
     ProtocolVersion     protocolVersion;
     RandomCookie        clnt_random;
@@ -225,37 +220,20 @@
 
     private final static byte[]  NULL_COMPRESSION = new byte[] {0};
 
-    ClientHello(SecureRandom generator, ProtocolVersion protocolVersion) {
+    ClientHello(SecureRandom generator, ProtocolVersion protocolVersion,
+            SessionId sessionId, CipherSuiteList cipherSuites) {
+
         this.protocolVersion = protocolVersion;
-        clnt_random = new RandomCookie(generator);
-        compression_methods = NULL_COMPRESSION;
-        // sessionId, cipher_suites TBS later
-    }
+        this.sessionId = sessionId;
+        this.cipherSuites = cipherSuites;
 
-    CipherSuiteList getCipherSuites() {
-        return cipherSuites;
-    }
-
-    // Set the ciphersuites.
-    // This method may only be called once.
-    void setCipherSuites(CipherSuiteList cipherSuites) {
-        this.cipherSuites = cipherSuites;
         if (cipherSuites.containsEC()) {
             extensions.add(SupportedEllipticCurvesExtension.DEFAULT);
             extensions.add(SupportedEllipticPointFormatsExtension.DEFAULT);
         }
-    }
 
-    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();
+        clnt_random = new RandomCookie(generator);
+        compression_methods = NULL_COMPRESSION;
     }
 
     ClientHello(HandshakeInStream s, int messageLength) throws IOException {
@@ -269,6 +247,34 @@
         }
     }
 
+    CipherSuiteList getCipherSuites() {
+        return cipherSuites;
+    }
+
+    // add renegotiation_info extension
+    void addRenegotiationInfoExtension(byte[] clientVerifyData) {
+        HelloExtension renegotiationInfo = new RenegotiationInfoExtension(
+                    clientVerifyData, new byte[0]);
+        extensions.add(renegotiationInfo);
+    }
+
+    @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);
@@ -279,6 +285,7 @@
         extensions.send(s);
     }
 
+    @Override
     void print(PrintStream s) throws IOException {
         s.println("*** ClientHello, " + protocolVersion);
 
@@ -315,7 +322,6 @@
     CipherSuite         cipherSuite;
     byte                compression_method;
     HelloExtensions extensions = new HelloExtensions();
-    int extensionLength;
 
     ServerHello() {
         // empty
@@ -1425,8 +1431,6 @@
  */
 static final class Finished extends HandshakeMessage {
 
-    int messageType() { return ht_finished; }
-
     // constant for a Finished message sent by the client
     final static int CLIENT = 1;
 
@@ -1468,7 +1472,7 @@
      * both client and server are fully in sync, and that the handshake
      * computations have been successful.
      */
-     boolean verify(ProtocolVersion protocolVersion,
+    boolean verify(ProtocolVersion protocolVersion,
              HandshakeHash handshakeHash, int sender, SecretKey master) {
         byte[] myFinished = getFinished(protocolVersion, handshakeHash,
                                         sender, master);
@@ -1542,14 +1546,25 @@
         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")) {
@@ -1557,7 +1572,6 @@
             s.println("***");
         }
     }
-
 }
 
 //
--- a/src/share/classes/sun/security/ssl/Handshaker.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/sun/security/ssl/Handshaker.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -66,6 +66,14 @@
     // 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
     ProtocolList enabledProtocols;
 
@@ -128,31 +136,66 @@
     static final Debug debug = Debug.getInstance("ssl");
 
     // By default, disable the unsafe legacy session renegotiation
-    static final boolean renegotiable = Debug.getBooleanProperty(
+    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) {
+            boolean isClient, ProtocolVersion activeProtocolVersion,
+            boolean isInitialHandshake, boolean secureRenegotiation,
+            byte[] clientVerifyData, byte[] serverVerifyData) {
         this.conn = c;
-        init(context, enabledProtocols, needCertVerify, isClient);
+        init(context, enabledProtocols, needCertVerify, isClient,
+            activeProtocolVersion, isInitialHandshake, secureRenegotiation,
+            clientVerifyData, serverVerifyData);
     }
 
     Handshaker(SSLEngineImpl engine, SSLContextImpl context,
             ProtocolList enabledProtocols, boolean needCertVerify,
-            boolean isClient) {
+            boolean isClient, ProtocolVersion activeProtocolVersion,
+            boolean isInitialHandshake, boolean secureRenegotiation,
+            byte[] clientVerifyData, byte[] serverVerifyData) {
         this.engine = engine;
-        init(context, enabledProtocols, needCertVerify, isClient);
+        init(context, enabledProtocols, needCertVerify, isClient,
+            activeProtocolVersion, isInitialHandshake, secureRenegotiation,
+            clientVerifyData, serverVerifyData);
     }
 
     private void init(SSLContextImpl context, ProtocolList enabledProtocols,
-            boolean needCertVerify, boolean isClient) {
+            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.activeProtocolVersion = activeProtocolVersion;
+        this.isInitialHandshake = isInitialHandshake;
+        this.secureRenegotiation = secureRenegotiation;
+        this.clientVerifyData = clientVerifyData;
+        this.serverVerifyData = serverVerifyData;
         enableNewSession = true;
         invalidated = false;
 
@@ -353,8 +396,8 @@
      * changed due to change in JCE providers since it was enabled).
      * Does not check if the required server certificates are available.
      */
-    boolean isEnabled(CipherSuite s) {
-        return enabledCipherSuites.contains(s) && s.isAvailable();
+    boolean isNegotiable(CipherSuite s) {
+        return enabledCipherSuites.contains(s) && s.isNegotiable();
     }
 
     /**
@@ -459,6 +502,27 @@
     }
 
     /*
+     * 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.
      */
--- a/src/share/classes/sun/security/ssl/HelloExtensions.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/sun/security/ssl/HelloExtensions.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -81,7 +81,10 @@
             } 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);
+                extension =
+                        new SupportedEllipticPointFormatsExtension(s, extlen);
+            } else if (extType == ExtensionType.EXT_RENEGOTIATION_INFO) {
+                extension = new RenegotiationInfoExtension(s, extlen);
             } else {
                 extension = new UnknownExtension(s, extlen, extType);
             }
@@ -89,7 +92,8 @@
             len -= extlen + 4;
         }
         if (len != 0) {
-            throw new SSLProtocolException("Error parsing extensions: extra data");
+            throw new SSLProtocolException(
+                        "Error parsing extensions: extra data");
         }
     }
 
@@ -162,7 +166,8 @@
         return name;
     }
 
-    static List<ExtensionType> knownExtensions = new ArrayList<ExtensionType>(8);
+    static List<ExtensionType> knownExtensions =
+                                            new ArrayList<ExtensionType>(9);
 
     static ExtensionType get(int id) {
         for (ExtensionType ext : knownExtensions) {
@@ -180,17 +185,44 @@
     }
 
     // extensions defined in RFC 3546
-    final static ExtensionType EXT_SERVER_NAME            = e( 0, "server_name");
-    final static ExtensionType EXT_MAX_FRAGMENT_LENGTH    = e( 1, "max_fragment_length");
-    final static ExtensionType EXT_CLIENT_CERTIFICATE_URL = e( 2, "client_certificate_url");
-    final static ExtensionType EXT_TRUSTED_CA_KEYS        = e( 3, "trusted_ca_keys");
-    final static ExtensionType EXT_TRUNCATED_HMAC         = e( 4, "truncated_hmac");
-    final static ExtensionType EXT_STATUS_REQUEST         = e( 5, "status_request");
+    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(10, "elliptic_curves");
-    final static ExtensionType EXT_EC_POINT_FORMATS       = e(11, "ec_point_formats");
+    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 {
@@ -238,9 +270,11 @@
     }
 }
 
-// Support for the server_name extension is incomplete. Parsing is implemented
-// so that we get nicer debug output, but we neither send it nor do we do
-// act on it if we receive it.
+/*
+ * Support for the server_name extension is incomplete. Parsing is implemented
+ * so that we get nicer debug output, but we neither send it nor do we do
+ * act on it if we receive it.
+ */
 final class ServerNameExtension extends HelloExtension {
 
     final static int NAME_HOST_NAME = 0;
@@ -268,9 +302,9 @@
         final String hostname;
 
         ServerName(HandshakeInStream s) throws IOException {
-            length = s.getInt16();
-            type = s.getInt8();
-            data = s.getBytes16();
+            length = s.getInt16();      // ServerNameList length
+            type = s.getInt8();         // NameType
+            data = s.getBytes16();      // HostName (length read in getBytes16)
             if (type == NAME_HOST_NAME) {
                 hostname = new String(data, "UTF8");
             } else {
@@ -549,3 +583,85 @@
         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));
+    }
+
+}
--- a/src/share/classes/sun/security/ssl/OutputRecord.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/sun/security/ssl/OutputRecord.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -343,6 +343,9 @@
      * 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
@@ -361,12 +364,21 @@
         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);
         }
 
         /*
--- a/src/share/classes/sun/security/ssl/SSLEngineImpl.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/sun/security/ssl/SSLEngineImpl.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -275,6 +275,12 @@
     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 *
@@ -356,6 +362,11 @@
         writeCipher = CipherBox.NULL;
         writeMAC = MAC.NULL;
 
+        // default security parameters for secure renegotiation
+        secureRenegotiation = false;
+        clientVerifyData = new byte[0];
+        serverVerifyData = new byte[0];
+
         enabledCipherSuites = CipherSuiteList.getDefault();
         enabledProtocols = ProtocolList.getDefault();
 
@@ -434,11 +445,14 @@
         }
         if (roleIsServer) {
             handshaker = new ServerHandshaker(this, sslContext,
-                        enabledProtocols, doClientAuth,
-                        connectionState == cs_RENEGOTIATE, protocolVersion);
+                    enabledProtocols, doClientAuth,
+                    protocolVersion, connectionState == cs_HANDSHAKE,
+                    secureRenegotiation, clientVerifyData, serverVerifyData);
         } else {
             handshaker = new ClientHandshaker(this, sslContext,
-                        enabledProtocols, protocolVersion);
+                    enabledProtocols,
+                    protocolVersion, connectionState == cs_HANDSHAKE,
+                    secureRenegotiation, clientVerifyData, serverVerifyData);
         }
         handshaker.enabledCipherSuites = enabledCipherSuites;
         handshaker.setEnableSessionCreation(enableSessionCreation);
@@ -640,8 +654,16 @@
             break;
 
         case cs_DATA:
-            if (!Handshaker.renegotiable) {
-                throw new SSLHandshakeException("renegotiation is not allowed");
+            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
@@ -978,6 +1000,12 @@
                             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();
                         if (!writer.hasOutboundData()) {
                             hsStatus = HandshakeStatus.FINISHED;
--- a/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -307,8 +307,9 @@
             try {
                 ServerHandshaker handshaker = tmp.getServerHandshaker();
 
-                for (Iterator t = enabledCipherSuites.iterator(); t.hasNext(); ) {
-                    CipherSuite suite = (CipherSuite)t.next();
+                for (Iterator<CipherSuite> t = enabledCipherSuites.iterator();
+                        t.hasNext();) {
+                    CipherSuite suite = t.next();
                     if (handshaker.trySetCipherSuite(suite)) {
                         checkedEnabled = true;
                         return;
--- a/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -275,9 +275,9 @@
      * This is necessary so that processing of close_notify alerts
      * from the peer are handled properly.
      */
-    private Object              handshakeLock;
-    ReentrantLock               writeLock;
-    private Object              readLock;
+    final private Object        handshakeLock = new Object();
+    final ReentrantLock         writeLock = new ReentrantLock();
+    final private Object        readLock = new Object();
 
     private InputRecord         inrec;
 
@@ -289,6 +289,13 @@
     // 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).
@@ -528,11 +535,13 @@
         writeCipher = CipherBox.NULL;
         writeMAC = MAC.NULL;
 
+        // initial security parameters for secure renegotiation
+        secureRenegotiation = false;
+        clientVerifyData = new byte[0];
+        serverVerifyData = new byte[0];
+
         enabledCipherSuites = CipherSuiteList.getDefault();
         enabledProtocols = ProtocolList.getDefault();
-        handshakeLock = new Object();
-        writeLock = new ReentrantLock();
-        readLock = new Object();
         inrec = null;
 
         // save the acc
@@ -914,6 +923,12 @@
                             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();
                         handshaker = null;
                         connectionState = cs_DATA;
@@ -1091,11 +1106,14 @@
         }
         if (roleIsServer) {
             handshaker = new ServerHandshaker(this, sslContext,
-                        enabledProtocols, doClientAuth,
-                        connectionState == cs_RENEGOTIATE, protocolVersion);
+                    enabledProtocols, doClientAuth,
+                    protocolVersion, connectionState == cs_HANDSHAKE,
+                    secureRenegotiation, clientVerifyData, serverVerifyData);
         } else {
             handshaker = new ClientHandshaker(this, sslContext,
-                        enabledProtocols, protocolVersion);
+                    enabledProtocols,
+                    protocolVersion, connectionState == cs_HANDSHAKE,
+                    secureRenegotiation, clientVerifyData, serverVerifyData);
         }
         handshaker.enabledCipherSuites = enabledCipherSuites;
         handshaker.setEnableSessionCreation(enableSessionCreation);
@@ -1200,8 +1218,16 @@
             break;
 
         case cs_DATA:
-            if (!Handshaker.renegotiable) {
-                throw new SSLHandshakeException("renegotiation is not allowed");
+            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
--- a/src/share/classes/sun/security/ssl/ServerHandshaker.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/classes/sun/security/ssl/ServerHandshaker.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -69,9 +69,6 @@
     // flag to check for clientCertificateVerify message
     private boolean             needClientVerify = false;
 
-    // indicate a renegotiation handshaking
-    private boolean             isRenegotiation = false;
-
     /*
      * For exportable ciphersuites using non-exportable key sizes, we use
      * ephemeral RSA keys. We could also do anonymous RSA in the same way
@@ -100,13 +97,15 @@
      */
     ServerHandshaker(SSLSocketImpl socket, SSLContextImpl context,
             ProtocolList enabledProtocols, byte clientAuth,
-            boolean isRenegotiation, ProtocolVersion activeProtocolVersion) {
+            ProtocolVersion activeProtocolVersion, boolean isInitialHandshake,
+            boolean secureRenegotiation,
+            byte[] clientVerifyData, byte[] serverVerifyData) {
 
         super(socket, context, enabledProtocols,
-                        (clientAuth != SSLEngineImpl.clauth_none), false);
+                (clientAuth != SSLEngineImpl.clauth_none), false,
+                activeProtocolVersion, isInitialHandshake, secureRenegotiation,
+                clientVerifyData, serverVerifyData);
         doClientAuth = clientAuth;
-        this.isRenegotiation = isRenegotiation;
-        this.activeProtocolVersion = activeProtocolVersion;
     }
 
     /*
@@ -114,13 +113,15 @@
      */
     ServerHandshaker(SSLEngineImpl engine, SSLContextImpl context,
             ProtocolList enabledProtocols, byte clientAuth,
-            boolean isRenegotiation, ProtocolVersion activeProtocolVersion) {
+            ProtocolVersion activeProtocolVersion,
+            boolean isInitialHandshake, boolean secureRenegotiation,
+            byte[] clientVerifyData, byte[] serverVerifyData) {
 
         super(engine, context, enabledProtocols,
-                        (clientAuth != SSLEngineImpl.clauth_none), false);
+                (clientAuth != SSLEngineImpl.clauth_none), false,
+                activeProtocolVersion, isInitialHandshake, secureRenegotiation,
+                clientVerifyData, serverVerifyData);
         doClientAuth = clientAuth;
-        this.isRenegotiation = isRenegotiation;
-        this.activeProtocolVersion = activeProtocolVersion;
     }
 
     /*
@@ -269,41 +270,122 @@
             mesg.print(System.out);
         }
 
-        // if it is a renegotiation request and renegotiation is not allowed
-        if (isRenegotiation && !renegotiable) {
-            if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) {
-                // response with a no_negotiation warning,
-                warningSE(Alerts.alert_no_negotiation);
+        // Does the message include security renegotiation indication?
+        boolean renegotiationIndicated = false;
 
-                // invalidate the handshake so that the caller can
-                // dispose this object.
-                invalidated = true;
+        // 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");
+                }
+            }
+        }
 
-                // 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");
-
+        // 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");
                 }
 
-                return;
+                secureRenegotiation = true;
             } else {
-                // For SSLv3, send the handshake_failure fatal error.
-                // Note that SSLv3 does not define a no_negotiation 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");
+                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");
+                }
             }
         }
 
@@ -454,7 +536,7 @@
                     // verify that the ciphersuite from the cached session
                     // is in the list of client requested ciphersuites and
                     // we have it enabled
-                    if ((isEnabled(suite) == false) ||
+                    if ((isNegotiable(suite) == false) ||
                             (mesg.getCipherSuites().contains(suite) == false)) {
                         resumingSession = false;
                     } else {
@@ -484,8 +566,8 @@
             if (!enableNewSession) {
                 throw new SSLException("Client did not resume a session");
             }
-            supportedCurves = (SupportedEllipticCurvesExtension)mesg.extensions.get
-                                        (ExtensionType.EXT_ELLIPTIC_CURVES);
+            supportedCurves = (SupportedEllipticCurvesExtension)
+                        mesg.extensions.get(ExtensionType.EXT_ELLIPTIC_CURVES);
             chooseCipherSuite(mesg);
             session = new SSLSessionImpl(protocolVersion, cipherSuite,
                 sslContext.getSecureRandom(),
@@ -498,6 +580,21 @@
         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());
@@ -686,11 +783,13 @@
      */
     private void chooseCipherSuite(ClientHello mesg) throws IOException {
         for (CipherSuite suite : mesg.getCipherSuites().collection()) {
-            if (isEnabled(suite) == false) {
+            if (isNegotiable(suite) == false) {
                 continue;
             }
+
             if (doClientAuth == SSLEngineImpl.clauth_required) {
-                if ((suite.keyExchange == K_DH_ANON) || (suite.keyExchange == K_ECDH_ANON)) {
+                if ((suite.keyExchange == K_DH_ANON) ||
+                    (suite.keyExchange == K_ECDH_ANON)) {
                     continue;
                 }
             }
@@ -728,7 +827,7 @@
             return true;
         }
 
-        if (suite.isAvailable() == false) {
+        if (suite.isNegotiable() == false) {
             return false;
         }
 
@@ -1136,6 +1235,13 @@
         }
 
         /*
+         * 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.
@@ -1185,6 +1291,13 @@
         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
--- a/src/share/native/sun/awt/image/BufImgSurfaceData.c	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/native/sun/awt/image/BufImgSurfaceData.c	Fri Oct 08 11:27:55 2010 +0100
@@ -48,9 +48,12 @@
 
 static jfieldID         rgbID;
 static jfieldID         mapSizeID;
-static jfieldID         CMpDataID;
+static jfieldID         colorDataID;
+static jfieldID         pDataID;
 static jfieldID         allGrayID;
 
+static jclass           clsICMCD;
+static jmethodID        initICMCDmID;
 /*
  * Class:     sun_awt_image_BufImgSurfaceData
  * Method:    initIDs
@@ -58,18 +61,23 @@
  */
 JNIEXPORT void JNICALL
 Java_sun_awt_image_BufImgSurfaceData_initIDs
-    (JNIEnv *env, jclass bisd, jclass icm)
+(JNIEnv *env, jclass bisd, jclass icm, jclass cd)
 {
     if (sizeof(BufImgRIPrivate) > SD_RASINFO_PRIVATE_SIZE) {
         JNU_ThrowInternalError(env, "Private RasInfo structure too large!");
         return;
     }
 
+    clsICMCD = (*env)->NewWeakGlobalRef(env, cd);
+    initICMCDmID = (*env)->GetMethodID(env, cd, "<init>", "(J)V");
+    pDataID = (*env)->GetFieldID(env, cd, "pData", "J");
+
     rgbID = (*env)->GetFieldID(env, icm, "rgb", "[I");
     allGrayID = (*env)->GetFieldID(env, icm, "allgrayopaque", "Z");
     mapSizeID = (*env)->GetFieldID(env, icm, "map_size", "I");
-    CMpDataID = (*env)->GetFieldID(env, icm, "pData", "J");
-    if (allGrayID == 0 || rgbID == 0 || mapSizeID == 0 || CMpDataID == 0) {
+    colorDataID = (*env)->GetFieldID(env, icm, "colorData",
+        "Lsun/awt/image/BufImgSurfaceData$ICMColorData;");
+    if (allGrayID == 0 || rgbID == 0 || mapSizeID == 0 || pDataID == 0|| colorDataID == 0 || initICMCDmID == 0) {
         JNU_ThrowInternalError(env, "Could not get field IDs");
     }
 }
@@ -81,18 +89,9 @@
  */
 JNIEXPORT void JNICALL
 Java_sun_awt_image_BufImgSurfaceData_freeNativeICMData
-    (JNIEnv *env, jclass sd, jobject icm)
+    (JNIEnv *env, jclass sd, jlong pData)
 {
-    jlong pData;
-    ColorData *cdata;
-
-    if (JNU_IsNull(env, icm)) {
-        JNU_ThrowNullPointerException(env, "IndexColorModel cannot be null");
-        return;
-    }
-
-    pData = (*env)->GetLongField (env, icm, CMpDataID);
-    cdata = (ColorData *)pData;
+    ColorData *cdata = (ColorData*)jlong_to_ptr(pData);
     freeICMColorData(cdata);
 }
 
@@ -263,32 +262,48 @@
 static ColorData *BufImg_SetupICM(JNIEnv *env,
                                   BufImgSDOps *bisdo)
 {
-    ColorData *cData;
+    ColorData *cData = NULL;
+    jobject colorData;
 
     if (JNU_IsNull(env, bisdo->icm)) {
         return (ColorData *) NULL;
     }
 
-    cData = (ColorData *) JNU_GetLongFieldAsPtr(env, bisdo->icm, CMpDataID);
+    colorData = (*env)->GetObjectField(env, bisdo->icm, colorDataID);
 
-    if (cData == NULL) {
-        cData = (ColorData*)calloc(1, sizeof(ColorData));
+    if (JNU_IsNull(env, colorData)) {
+        if (JNU_IsNull(env, clsICMCD)) {
+            // we are unable to create a wrapper object
+            return (ColorData*)NULL;
+        }
+    } else {
+        cData = (ColorData*)JNU_GetLongFieldAsPtr(env, colorData, pDataID);
+    }
 
-        if (cData != NULL) {
-            jboolean allGray
-                = (*env)->GetBooleanField(env, bisdo->icm, allGrayID);
-            int *pRgb = (int *)
-                ((*env)->GetPrimitiveArrayCritical(env, bisdo->lutarray, NULL));
-            cData->img_clr_tbl = initCubemap(pRgb, bisdo->lutsize, 32);
-            if (allGray == JNI_TRUE) {
-                initInverseGrayLut(pRgb, bisdo->lutsize, cData);
-            }
-            (*env)->ReleasePrimitiveArrayCritical(env, bisdo->lutarray, pRgb,
-                                                  JNI_ABORT);
+    if (cData != NULL) {
+        return cData;
+    }
 
-            initDitherTables(cData);
+    cData = (ColorData*)calloc(1, sizeof(ColorData));
 
-            JNU_SetLongFieldFromPtr(env, bisdo->icm, CMpDataID, cData);
+    if (cData != NULL) {
+        jboolean allGray
+            = (*env)->GetBooleanField(env, bisdo->icm, allGrayID);
+        int *pRgb = (int *)
+            ((*env)->GetPrimitiveArrayCritical(env, bisdo->lutarray, NULL));
+        cData->img_clr_tbl = initCubemap(pRgb, bisdo->lutsize, 32);
+        if (allGray == JNI_TRUE) {
+            initInverseGrayLut(pRgb, bisdo->lutsize, cData);
+        }
+        (*env)->ReleasePrimitiveArrayCritical(env, bisdo->lutarray, pRgb,
+                                              JNI_ABORT);
+
+        initDitherTables(cData);
+
+        if (JNU_IsNull(env, colorData)) {
+            jlong pData = ptr_to_jlong(cData);
+            colorData = (*env)->NewObjectA(env, clsICMCD, initICMCDmID, (jvalue *)&pData);
+            (*env)->SetObjectField(env, bisdo->icm, colorDataID, colorData);
         }
     }
 
--- a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c	Thu Oct 07 11:35:48 2010 -0700
+++ b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c	Fri Oct 08 11:27:55 2010 +0100
@@ -2614,7 +2614,8 @@
     JSAMPROW scanLinePtr;
     int i, j;
     int pixelStride;
-    unsigned char *in, *out, *pixelLimit;
+    unsigned char *in, *out, *pixelLimit, *scanLineLimit;
+    unsigned int scanLineSize, pixelBufferSize;
     int targetLine;
     pixelBufferPtr pb;
     sun_jpeg_error_ptr jerr;
@@ -2650,19 +2651,25 @@
 
     }
 
+    scanLineSize = destWidth * numBands;
     if ((inCs < 0) || (inCs > JCS_YCCK) ||
         (outCs < 0) || (outCs > JCS_YCCK) ||
         (numBands < 1) || (numBands > MAX_BANDS) ||
         (srcWidth < 0) ||
         (destWidth < 0) || (destWidth > srcWidth) ||
         (destHeight < 0) ||
-        (stepX < 0) || (stepY < 0))
+        (stepX < 0) || (stepY < 0) ||
+        ((scanLineSize / numBands) < destWidth))  /* destWidth causes an integer overflow */
     {
         JNU_ThrowByName(env, "javax/imageio/IIOException",
                         "Invalid argument to native writeImage");
         return JNI_FALSE;
     }
 
+    if (stepX > srcWidth) {
+        stepX = srcWidth;
+    }
+
     bandSize = (*env)->GetIntArrayElements(env, bandSizes, NULL);
 
     for (i = 0; i < numBands; i++) {
@@ -2710,7 +2717,7 @@
     }
 
     // Allocate a 1-scanline buffer
-    scanLinePtr = (JSAMPROW)malloc(destWidth*numBands);
+    scanLinePtr = (JSAMPROW)malloc(scanLineSize);
     if (scanLinePtr == NULL) {
         RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
         JNU_ThrowByName( env,
@@ -2718,6 +2725,7 @@
                          "Writing JPEG Stream");
         return data->abortFlag;
     }
+    scanLineLimit = scanLinePtr + scanLineSize;
 
     /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
     jerr = (sun_jpeg_error_ptr) cinfo->err;
@@ -2866,6 +2874,8 @@
     }
 
     targetLine = 0;
+    pixelBufferSize = srcWidth * numBands;
+    pixelStride = numBands * stepX;
 
     // for each line in destHeight
     while ((data->abortFlag == JNI_FALSE)
@@ -2886,9 +2896,9 @@
 
         in = data->pixelBuf.buf.bp;
         out = scanLinePtr;
-        pixelLimit = in + srcWidth*numBands;
-        pixelStride = numBands*stepX;
-        for (; in < pixelLimit; in += pixelStride) {
+        pixelLimit = in + ((pixelBufferSize > data->pixelBuf.byteBufferLength) ?
+                           data->pixelBuf.byteBufferLength : pixelBufferSize);
+        for (; (in < pixelLimit) && (out < scanLineLimit); in += pixelStride) {
             for (i = 0; i < numBands; i++) {
                 if (scale !=NULL && scale[i] != NULL) {
                     *out++ = scale[i][*(in+i)];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/swing/Security/6938813/bug6938813.java	Fri Oct 08 11:27:55 2010 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 6938813
+ * @summary Swing mutable statics
+ * @author Pavel Porvatov
+ */
+
+import sun.awt.AppContext;
+import sun.awt.SunToolkit;
+
+import javax.swing.text.html.HTMLEditorKit;
+import javax.swing.text.html.StyleSheet;
+import javax.swing.text.html.parser.DTD;
+import javax.swing.text.html.parser.ParserDelegator;
+import java.lang.reflect.Field;
+
+public class bug6938813 {
+    public static final String DTD_KEY = "dtd_key";
+
+    private static volatile StyleSheet styleSheet;
+
+    public static void main(String[] args) throws Exception {
+        // Run validation and init values for this AppContext
+        validate();
+
+        Thread thread = new ThreadInAnotherAppContext();
+
+        thread.start();
+        thread.join();
+    }
+
+    private static void validate() throws Exception {
+        AppContext appContext = AppContext.getAppContext();
+
+        assertTrue(DTD.getDTD(DTD_KEY).getName().equals(DTD_KEY), "DTD.getDTD() mixed AppContexts");
+
+        // Spoil hash value
+        DTD invalidDtd = DTD.getDTD("invalid DTD");
+
+        DTD.putDTDHash(DTD_KEY, invalidDtd);
+
+        assertTrue(DTD.getDTD(DTD_KEY) == invalidDtd, "Something wrong with DTD.getDTD()");
+
+        Object dtdKey = getParserDelegator_DTD_KEY();
+
+        assertTrue(appContext.get(dtdKey) == null, "ParserDelegator mixed AppContexts");
+
+        // Init default DTD
+        new ParserDelegator();
+
+        Object dtdValue = appContext.get(dtdKey);
+
+        assertTrue(dtdValue != null, "ParserDelegator.defaultDTD isn't initialized");
+
+        // Try reinit default DTD
+        new ParserDelegator();
+
+        assertTrue(dtdValue == appContext.get(dtdKey), "ParserDelegator.defaultDTD created a duplicate");
+
+        HTMLEditorKit htmlEditorKit = new HTMLEditorKit();
+
+        if (styleSheet == null) {
+            // First AppContext
+            styleSheet = htmlEditorKit.getStyleSheet();
+
+            assertTrue(styleSheet != null, "htmlEditorKit.getStyleSheet() returns null");
+            assertTrue(htmlEditorKit.getStyleSheet() == styleSheet, "Something wrong with htmlEditorKit.getStyleSheet()");
+        } else {
+            assertTrue(htmlEditorKit.getStyleSheet() != styleSheet, "HtmlEditorKit.getStyleSheet() mixed AppContexts");
+        }
+    }
+
+    private static void assertTrue(boolean b, String msg) {
+        if (!b) {
+            throw new RuntimeException("Test failed: " + msg);
+        }
+    }
+
+    private static Object getParserDelegator_DTD_KEY() throws Exception {
+        Field field = ParserDelegator.class.getDeclaredField("DTD_KEY");
+
+        field.setAccessible(true);
+
+        return field.get(null);
+    }
+
+    private static class ThreadInAnotherAppContext extends Thread {
+        public ThreadInAnotherAppContext() {
+            super(new ThreadGroup("6938813"), "ThreadInAnotherAppContext");
+        }
+
+        public void run() {
+            SunToolkit.createNewAppContext();
+
+            try {
+                validate();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/swing/UIDefaults/6622002/bug6622002.java	Fri Oct 08 11:27:55 2010 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 6622002
+ * @author Alexander Potochkin
+ * @summary UIDefault.ProxyLazyValue has unsafe reflection usage
+ */
+
+import javax.swing.*;
+
+public class bug6622002 {
+     public static void main(String[] args) {
+
+         if (createPrivateValue() == null) {
+             throw new RuntimeException("The private value unexpectedly wasn't created");
+         }
+
+         if (createPublicValue() == null) {
+             throw new RuntimeException("The public value unexpectedly wasn't created");
+         }
+
+         System.setSecurityManager(new SecurityManager());
+
+         if (createPrivateValue() != null) {
+             throw new RuntimeException("The private value was unexpectedly created");
+         }
+
+         if (createPublicValue() == null) {
+             throw new RuntimeException("The public value unexpectedly wasn't created");
+         }
+     }
+
+    private static Object createPrivateValue() {
+        return new UIDefaults.ProxyLazyValue(
+            "javax.swing.MultiUIDefaults").createValue(null);
+    }
+
+    private static Object createPublicValue() {
+        return new UIDefaults.ProxyLazyValue(
+            "javax.swing.UIDefaults").createValue(null);
+    }
+}
--- a/test/sun/security/pkcs11/fips/CipherTest.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/test/sun/security/pkcs11/fips/CipherTest.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -114,10 +114,11 @@
         }
 
         boolean isEnabled() {
-//          return cipherSuite.equals("SSL_RSA_WITH_RC4_128_MD5") &&
-//              (clientAuth != null);
-//      return cipherSuite.indexOf("_RSA_") != -1;
-//      return cipherSuite.indexOf("DH_anon") != -1;
+            // ignore SCSV
+            if (cipherSuite.equals("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) {
+                return false;
+            }
+
             return true;
         }
 
--- a/test/sun/security/pkcs11/sslecc/CipherTest.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/test/sun/security/pkcs11/sslecc/CipherTest.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -114,12 +114,11 @@
         }
 
         boolean isEnabled() {
-//          if (true) return cipherSuite.contains("_ECDH_");
-//          return cipherSuite.equals("SSL_RSA_WITH_RC4_128_MD5") &&
-//              (clientAuth != null);
-//      return cipherSuite.indexOf("_RSA_") != -1;
-//      return cipherSuite.indexOf("DH_anon") != -1;
-//              return cipherSuite.contains("ECDSA") == false;
+            // ignore SCSV
+            if (cipherSuite.equals("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) {
+                return false;
+            }
+
             return true;
         }
 
--- a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/InvalidateServerSessionRenegotiate.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/InvalidateServerSessionRenegotiate.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,8 +25,6 @@
  * @test
  * @bug 4403428
  * @summary Invalidating JSSE session on server causes SSLProtocolException
- * @ignore incompatible with disabled unsafe renegotiation (6898739), please
- *         reenable when safe renegotiation is implemented.
  * @author Brad Wetmore
  */
 
--- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/JSSERenegotiate.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/JSSERenegotiate.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -26,8 +26,6 @@
  * @bug 4280338
  * @summary "Unsupported SSL message version" SSLProtocolException
  *      w/SSL_RSA_WITH_NULL_MD5
- * @ignore incompatible with disabled unsafe renegotiation (6898739), please
- *         reenable when safe renegotiation is implemented.
  *
  * @author Ram Marti
  * @author Brad Wetmore
--- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,8 +25,6 @@
  * @test
  * @bug 4948079
  * @summary SSLEngineResult needs updating [none yet]
- * @ignore incompatible with disabled unsafe renegotiation (6898739), please
- *         reenable when safe renegotiation is implemented.
  *
  * This is a simple hack to test a bunch of conditions and check
  * their return codes.
--- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/ConnectionTest.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/ConnectionTest.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -26,8 +26,6 @@
  * @bug 4495742
  * @summary Add non-blocking SSL/TLS functionality, usable with any
  *      I/O abstraction
- * @ignore incompatible with disabled unsafe renegotiation (6898739), please
- *         reenable when safe renegotiation is implemented.
  *
  * This is a bit hacky, meant to test various conditions.  The main
  * thing I wanted to do with this was to do buffer reads/writes
--- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/NoAuthClientAuth.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/NoAuthClientAuth.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,8 +25,6 @@
  * @test
  * @bug 4495742
  * @summary Demonstrate SSLEngine switch from no client auth to client auth.
- * @ignore incompatible with disabled unsafe renegotiation (6898739), please
- *         reenable when safe renegotiation is implemented.
  *
  * @author Brad R. Wetmore
  */
--- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/TestAllSuites.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/TestAllSuites.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -119,6 +119,15 @@
             return;
         }
 
+        /*
+         * Don't run the SCSV suite
+         */
+        if (suite.equals("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) {
+            System.out.println("Ignoring SCSV suite");
+            return;
+        }
+
+
         if (!suite.contains("DH_anon")) {
             ssle2.setNeedClientAuth(true);
         }
--- a/test/sun/security/ssl/sanity/ciphersuites/CheckCipherSuites.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/test/sun/security/ssl/sanity/ciphersuites/CheckCipherSuites.java	Fri Oct 08 11:27:55 2010 +0100
@@ -64,6 +64,8 @@
         "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
         "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
         "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+        "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
+
     };
 
     private final static String[] ENABLED_UNLIMITED = {
@@ -101,6 +103,8 @@
         "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
         "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
         "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+        "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
+
     };
 
     // supported ciphersuites using default JCE policy jurisdiction files
@@ -133,6 +137,7 @@
         "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
         "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
         "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+        "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
 
         "SSL_RSA_WITH_NULL_MD5",
         "SSL_RSA_WITH_NULL_SHA",
@@ -160,6 +165,7 @@
         "TLS_KRB5_EXPORT_WITH_RC4_40_MD5",
         "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA",
         "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5",
+
     };
 
     // supported ciphersuites using unlimited JCE policy jurisdiction files
@@ -199,6 +205,7 @@
         "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
         "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
         "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+        "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
 
         "SSL_RSA_WITH_NULL_MD5",
         "SSL_RSA_WITH_NULL_SHA",
@@ -228,6 +235,7 @@
         "TLS_KRB5_EXPORT_WITH_RC4_40_MD5",
         "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA",
         "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5",
+
     };
 
     private static void showSuites(String[] suites) {
--- a/test/sun/security/ssl/sanity/interop/CipherTest.java	Thu Oct 07 11:35:48 2010 -0700
+++ b/test/sun/security/ssl/sanity/interop/CipherTest.java	Fri Oct 08 11:27:55 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -115,10 +115,11 @@
         }
 
         boolean isEnabled() {
-//          return cipherSuite.equals("SSL_RSA_WITH_RC4_128_MD5") &&
-//              (clientAuth != null);
-//      return cipherSuite.indexOf("_RSA_") != -1;
-//      return cipherSuite.indexOf("DH_anon") != -1;
+            // ignore SCSV
+            if (cipherSuite.equals("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) {
+                return false;
+            }
+
             return true;
         }