changeset 12398:37f8939fb535

Merge
author henryjen
date Wed, 15 Jul 2015 06:42:49 -0700
parents 6c0e4a3e5f69 c557041ff58f
children d84d9dc7b20f
files
diffstat 91 files changed, 1404 insertions(+), 718 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/macosx/native/libjli/java_md_macosx.c	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/macosx/native/libjli/java_md_macosx.c	Wed Jul 15 06:42:49 2015 -0700
@@ -611,7 +611,11 @@
         if (access(libjava, F_OK) == 0) {
             return JNI_TRUE;
         }
-
+        /* ensure storage for path + /jre + NULL */
+        if ((JLI_StrLen(path) + 4 + 1) > (size_t) pathsize) {
+            JLI_TraceLauncher("Insufficient space to store JRE path\n");
+            return JNI_FALSE;
+        }
         /* Does the app ship a private JRE in <apphome>/jre directory? */
         JLI_Snprintf(libjava, sizeof(libjava), "%s/jre/lib/" JAVA_DLL, path);
         if (access(libjava, F_OK) == 0) {
--- a/src/java.base/share/classes/com/sun/crypto/provider/AESCrypt.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/com/sun/crypto/provider/AESCrypt.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, 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
@@ -37,6 +37,7 @@
 package com.sun.crypto.provider;
 
 import java.security.InvalidKeyException;
+import java.security.MessageDigest;
 import java.util.Arrays;
 import java.util.Objects;
 
@@ -91,7 +92,7 @@
                 key.length + " bytes");
         }
 
-        if (!Arrays.equals(key, lastKey)) {
+        if (!MessageDigest.isEqual(key, lastKey)) {
             // re-generate session key 'sessionK' when cipher key changes
             makeSessionKey(key);
             lastKey = key.clone();  // save cipher key
--- a/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, 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
@@ -568,7 +568,7 @@
                 // check key+iv for encryption in GCM mode
                 requireReinit =
                     Arrays.equals(ivBytes, lastEncIv) &&
-                    Arrays.equals(keyBytes, lastEncKey);
+                    MessageDigest.isEqual(keyBytes, lastEncKey);
                 if (requireReinit) {
                     throw new InvalidAlgorithmParameterException
                         ("Cannot reuse iv for GCM encryption");
--- a/src/java.base/share/classes/com/sun/crypto/provider/DESKey.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/com/sun/crypto/provider/DESKey.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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,7 @@
 
 package com.sun.crypto.provider;
 
+import java.security.MessageDigest;
 import java.security.KeyRep;
 import java.security.InvalidKeyException;
 import javax.crypto.SecretKey;
@@ -113,7 +114,7 @@
             return false;
 
         byte[] thatKey = ((SecretKey)obj).getEncoded();
-        boolean ret = java.util.Arrays.equals(this.key, thatKey);
+        boolean ret = MessageDigest.isEqual(this.key, thatKey);
         java.util.Arrays.fill(thatKey, (byte)0x00);
         return ret;
     }
--- a/src/java.base/share/classes/com/sun/crypto/provider/DESedeKey.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/com/sun/crypto/provider/DESedeKey.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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,7 @@
 
 package com.sun.crypto.provider;
 
+import java.security.MessageDigest;
 import java.security.KeyRep;
 import java.security.InvalidKeyException;
 import javax.crypto.SecretKey;
@@ -114,7 +115,7 @@
             return false;
 
         byte[] thatKey = ((SecretKey)obj).getEncoded();
-        boolean ret = java.util.Arrays.equals(this.key, thatKey);
+        boolean ret = MessageDigest.isEqual(this.key, thatKey);
         java.util.Arrays.fill(thatKey, (byte)0x00);
         return ret;
     }
--- a/src/java.base/share/classes/com/sun/crypto/provider/PBEKey.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/com/sun/crypto/provider/PBEKey.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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,7 @@
 
 package com.sun.crypto.provider;
 
+import java.security.MessageDigest;
 import java.security.KeyRep;
 import java.security.spec.InvalidKeySpecException;
 import java.util.Locale;
@@ -108,7 +109,7 @@
             return false;
 
         byte[] thatEncoded = that.getEncoded();
-        boolean ret = java.util.Arrays.equals(this.key, thatEncoded);
+        boolean ret = MessageDigest.isEqual(this.key, thatEncoded);
         java.util.Arrays.fill(thatEncoded, (byte)0x00);
         return ret;
     }
--- a/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, 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
@@ -31,6 +31,7 @@
 import java.nio.charset.Charset;
 import java.util.Arrays;
 import java.util.Locale;
+import java.security.MessageDigest;
 import java.security.KeyRep;
 import java.security.GeneralSecurityException;
 import java.security.NoSuchAlgorithmException;
@@ -153,7 +154,7 @@
                     SecretKey sk = (SecretKey)obj;
                     return prf.getAlgorithm().equalsIgnoreCase(
                         sk.getAlgorithm()) &&
-                        Arrays.equals(password, sk.getEncoded());
+                        MessageDigest.isEqual(password, sk.getEncoded());
                 }
             };
             prf.init(macKey);
@@ -239,7 +240,7 @@
         if (!(that.getFormat().equalsIgnoreCase("RAW")))
             return false;
         byte[] thatEncoded = that.getEncoded();
-        boolean ret = Arrays.equals(key, that.getEncoded());
+        boolean ret = MessageDigest.isEqual(key, that.getEncoded());
         java.util.Arrays.fill(thatEncoded, (byte)0x00);
         return ret;
     }
--- a/src/java.base/share/classes/java/io/ObjectInputStream.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/java/io/ObjectInputStream.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1832,6 +1832,8 @@
         throws IOException
     {
         SerialCallbackContext oldContext = curContext;
+        if (oldContext != null)
+            oldContext.check();
         curContext = null;
         try {
             boolean blocked = desc.hasBlockExternalData();
@@ -1856,6 +1858,8 @@
                 skipCustomData();
             }
         } finally {
+            if (oldContext != null)
+                oldContext.check();
             curContext = oldContext;
         }
         /*
@@ -1906,12 +1910,12 @@
             ObjectStreamClass slotDesc = slots[i].desc;
 
             if (slots[i].hasData) {
-                if (obj != null &&
-                    slotDesc.hasReadObjectMethod() &&
-                    handles.lookupException(passHandle) == null)
-                {
+                if (obj == null || handles.lookupException(passHandle) != null) {
+                    defaultReadFields(null, slotDesc); // skip field values
+                } else if (slotDesc.hasReadObjectMethod()) {
                     SerialCallbackContext oldContext = curContext;
-
+                    if (oldContext != null)
+                        oldContext.check();
                     try {
                         curContext = new SerialCallbackContext(obj, slotDesc);
 
@@ -1928,6 +1932,8 @@
                         handles.markException(passHandle, ex);
                     } finally {
                         curContext.setUsed();
+                        if (oldContext!= null)
+                            oldContext.check();
                         curContext = oldContext;
                     }
 
@@ -1946,6 +1952,7 @@
                         defaultSetFieldValues(obj, slotDesc, vals);
                     }
                 }
+
                 if (slotDesc.hasWriteObjectData()) {
                     skipCustomData();
                 } else {
--- a/src/java.base/share/classes/java/io/SerialCallbackContext.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/java/io/SerialCallbackContext.java	Wed Jul 15 06:42:49 2015 -0700
@@ -60,6 +60,13 @@
         return desc;
     }
 
+    public void check() throws NotActiveException {
+        if (thread != null && thread != Thread.currentThread()) {
+            throw new NotActiveException(
+                "expected thread: " + thread + ", but got: " + Thread.currentThread());
+        }
+    }
+
     public void checkAndSetUsed() throws NotActiveException {
         if (thread != Thread.currentThread()) {
              throw new NotActiveException(
--- a/src/java.base/share/classes/java/net/InetAddress.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/java/net/InetAddress.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2015, 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
@@ -205,16 +205,33 @@
     static transient boolean preferIPv6Address = false;
 
     static class InetAddressHolder {
+        /**
+         * Reserve the original application specified hostname.
+         *
+         * The original hostname is useful for domain-based endpoint
+         * identification (see RFC 2818 and RFC 6125).  If an address
+         * was created with a raw IP address, a reverse name lookup
+         * may introduce endpoint identification security issue via
+         * DNS forging.
+         *
+         * Oracle JSSE provider is using this original hostname, via
+         * sun.misc.JavaNetAccess, for SSL/TLS endpoint identification.
+         *
+         * Note: May define a new public method in the future if necessary.
+         */
+        private String originalHostName;
 
         InetAddressHolder() {}
 
         InetAddressHolder(String hostName, int address, int family) {
+            this.originalHostName = hostName;
             this.hostName = hostName;
             this.address = address;
             this.family = family;
         }
 
         void init(String hostName, int family) {
+            this.originalHostName = hostName;
             this.hostName = hostName;
             if (family != -1) {
                 this.family = family;
@@ -227,6 +244,10 @@
             return hostName;
         }
 
+        String getOriginalHostName() {
+            return originalHostName;
+        }
+
         /**
          * Holds a 32-bit IPv4 address.
          */
--- a/src/java.base/share/classes/java/net/URLClassLoader.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/java/net/URLClassLoader.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -774,6 +774,10 @@
                 public URLClassPath getURLClassPath (URLClassLoader u) {
                     return u.ucp;
                 }
+
+                public String getOriginalHostName(InetAddress ia) {
+                    return ia.holder.getOriginalHostName();
+                }
             }
         );
         ClassLoader.registerAsParallelCapable();
--- a/src/java.base/share/classes/java/security/Identity.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/java/security/Identity.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, 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
@@ -261,7 +261,7 @@
         certificates.addElement(certificate);
     }
 
-    private boolean keyEquals(Key aKey, Key anotherKey) {
+    private boolean keyEquals(PublicKey aKey, PublicKey anotherKey) {
         String aKeyFormat = aKey.getFormat();
         String anotherKeyFormat = anotherKey.getFormat();
         if ((aKeyFormat == null) ^ (anotherKeyFormat == null))
--- a/src/java.base/share/classes/java/security/MessageDigest.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/java/security/MessageDigest.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, 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
@@ -440,6 +440,10 @@
      * @return true if the digests are equal, false otherwise.
      */
     public static boolean isEqual(byte[] digesta, byte[] digestb) {
+        if (digesta == digestb) return true;
+        if (digesta == null || digestb == null) {
+            return false;
+        }
         if (digesta.length != digestb.length) {
             return false;
         }
--- a/src/java.base/share/classes/java/security/Signature.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/java/security/Signature.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, 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
@@ -1324,7 +1324,7 @@
                 byte[] out = cipher.doFinal(sigBytes);
                 byte[] dataBytes = data.toByteArray();
                 data.reset();
-                return Arrays.equals(out, dataBytes);
+                return MessageDigest.isEqual(out, dataBytes);
             } catch (BadPaddingException e) {
                 // e.g. wrong public key used
                 // return false rather than throwing exception
--- a/src/java.base/share/classes/java/security/cert/X509CRLSelector.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/java/security/cert/X509CRLSelector.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -679,10 +679,14 @@
                 nowPlusSkew = new Date(dateAndTime.getTime() + skew);
                 nowMinusSkew = new Date(dateAndTime.getTime() - skew);
             }
+
+            // Check that the test date is within the validity interval:
+            //   [ thisUpdate - MAX_CLOCK_SKEW,
+            //     nextUpdate + MAX_CLOCK_SKEW ]
             if (nowMinusSkew.after(nextUpdate)
                 || nowPlusSkew.before(crlThisUpdate)) {
                 if (debug != null) {
-                    debug.println("X509CRLSelector.match: update out of range");
+                    debug.println("X509CRLSelector.match: update out-of-range");
                 }
                 return false;
             }
--- a/src/java.base/share/classes/javax/crypto/spec/SecretKeySpec.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/javax/crypto/spec/SecretKeySpec.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, 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,7 @@
 
 package javax.crypto.spec;
 
+import java.security.MessageDigest;
 import java.security.spec.KeySpec;
 import java.util.Locale;
 import javax.crypto.SecretKey;
@@ -228,6 +229,6 @@
 
         byte[] thatKey = ((SecretKey)obj).getEncoded();
 
-        return java.util.Arrays.equals(this.key, thatKey);
+        return MessageDigest.isEqual(this.key, thatKey);
     }
 }
--- a/src/java.base/share/classes/sun/misc/JavaNetAccess.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/misc/JavaNetAccess.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015, 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,10 +26,17 @@
 package sun.misc;
 
 import java.net.URLClassLoader;
+import java.net.InetAddress;
 
 public interface JavaNetAccess {
     /**
      * return the URLClassPath belonging to the given loader
      */
     URLClassPath getURLClassPath (URLClassLoader u);
+
+    /**
+     * Return the original application specified hostname of
+     * the given InetAddress object.
+     */
+    String getOriginalHostName(InetAddress ia);
 }
--- a/src/java.base/share/classes/sun/net/util/URLUtil.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/net/util/URLUtil.java	Wed Jul 15 06:42:49 2015 -0700
@@ -25,7 +25,10 @@
 
 package sun.net.util;
 
+import java.io.IOException;
 import java.net.URL;
+import java.net.URLPermission;
+import java.security.Permission;
 
 /**
  * URL Utility class.
@@ -76,5 +79,26 @@
 
         return strForm.toString();
     }
+
+    public static Permission getConnectPermission(URL url) throws IOException {
+        String urlStringLowerCase = url.toString().toLowerCase();
+        if (urlStringLowerCase.startsWith("http:") || urlStringLowerCase.startsWith("https:")) {
+            return getURLConnectPermission(url);
+        } else if (urlStringLowerCase.startsWith("jar:http:") || urlStringLowerCase.startsWith("jar:https:")) {
+            String urlString = url.toString();
+            int bangPos = urlString.indexOf("!/");
+            urlString = urlString.substring(4, bangPos > -1 ? bangPos : urlString.length());
+            URL u = new URL(urlString);
+            return getURLConnectPermission(u);
+            // If protocol is HTTP or HTTPS than use URLPermission object
+        } else {
+            return url.openConnection().getPermission();
+        }
+    }
+
+    private static Permission getURLConnectPermission(URL url) {
+        String urlString = url.getProtocol() + "://" + url.getAuthority() + url.getPath();
+        return new URLPermission(urlString);
+    }
 }
 
--- a/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Wed Jul 15 06:42:49 2015 -0700
@@ -2059,7 +2059,7 @@
                         "(MAC algorithm: " + m.getAlgorithm() + ")");
                 }
 
-                if (!Arrays.equals(macData.getDigest(), macResult)) {
+                if (!MessageDigest.isEqual(macData.getDigest(), macResult)) {
                    throw new SecurityException("Failed PKCS12" +
                                         " integrity checking");
                 }
--- a/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java	Wed Jul 15 06:42:49 2015 -0700
@@ -151,8 +151,8 @@
     private static final int DEFAULT_MAX_CLOCK_SKEW = 900000;
 
     /**
-     * Integer value indicating the maximum allowable clock skew, in seconds,
-     * to be used for the OCSP check.
+     * Integer value indicating the maximum allowable clock skew,
+     * in milliseconds, to be used for the OCSP check.
      */
     private static final int MAX_CLOCK_SKEW = initializeClockSkew();
 
@@ -585,13 +585,14 @@
                 "Unable to verify OCSP Response's signature");
         }
 
-        // Check freshness of OCSPResponse
         if (nonce != null) {
             if (responseNonce != null && !Arrays.equals(nonce, responseNonce)) {
                 throw new CertPathValidatorException("Nonces don't match");
             }
         }
 
+        // Check freshness of OCSPResponse
+
         long now = (date == null) ? System.currentTimeMillis() : date.getTime();
         Date nowPlusSkew = new Date(now + MAX_CLOCK_SKEW);
         Date nowMinusSkew = new Date(now - MAX_CLOCK_SKEW);
@@ -601,13 +602,18 @@
                 if (sr.nextUpdate != null) {
                     until = " until " + sr.nextUpdate;
                 }
-                debug.println("Response's validity interval is from " +
+                debug.println("OCSP response validity interval is from " +
                               sr.thisUpdate + until);
+                debug.println("Checking validity of OCSP response on: " +
+                    new Date(now));
             }
 
-            // Check that the test date is within the validity interval
-            if ((sr.thisUpdate != null && nowPlusSkew.before(sr.thisUpdate)) ||
-                (sr.nextUpdate != null && nowMinusSkew.after(sr.nextUpdate)))
+            // Check that the test date is within the validity interval:
+            //   [ thisUpdate - MAX_CLOCK_SKEW,
+            //     MAX(thisUpdate, nextUpdate) + MAX_CLOCK_SKEW ]
+            if (nowPlusSkew.before(sr.thisUpdate) ||
+                nowMinusSkew.after(
+                    sr.nextUpdate != null ? sr.nextUpdate : sr.thisUpdate))
             {
                 throw new CertPathValidatorException(
                                       "Response is unreliable: its validity " +
--- a/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -159,12 +159,19 @@
                                                         ValidatorParams params)
         throws CertPathValidatorException
     {
+        // check if anchor is untrusted
+        UntrustedChecker untrustedChecker = new UntrustedChecker();
+        X509Certificate anchorCert = anchor.getTrustedCert();
+        if (anchorCert != null) {
+            untrustedChecker.check(anchorCert);
+        }
+
         int certPathLen = params.certificates().size();
 
         // create PKIXCertPathCheckers
         List<PKIXCertPathChecker> certPathCheckers = new ArrayList<>();
         // add standard checkers that we will be using
-        certPathCheckers.add(new UntrustedChecker());
+        certPathCheckers.add(untrustedChecker);
         certPathCheckers.add(new AlgorithmChecker(anchor));
         certPathCheckers.add(new KeyChecker(certPathLen,
                                             params.targetCertConstraints()));
--- a/src/java.base/share/classes/sun/security/rsa/RSASignature.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/security/rsa/RSASignature.java	Wed Jul 15 06:42:49 2015 -0700
@@ -27,7 +27,6 @@
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
-import java.util.Arrays;
 
 import java.security.*;
 import java.security.interfaces.*;
@@ -194,7 +193,7 @@
             byte[] decrypted = RSACore.rsa(sigBytes, publicKey);
             byte[] unpadded = padding.unpad(decrypted);
             byte[] decodedDigest = decodeSignature(digestOID, unpadded);
-            return Arrays.equals(digest, decodedDigest);
+            return MessageDigest.isEqual(digest, decodedDigest);
         } catch (javax.crypto.BadPaddingException e) {
             // occurs if the app has used the wrong RSA public key
             // or if sigBytes is invalid
--- a/src/java.base/share/classes/sun/security/ssl/CipherSuite.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/security/ssl/CipherSuite.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1008,7 +1008,7 @@
          * 1. Prefer Suite B compliant cipher suites, see RFC6460 (To be
          *    changed later, see below).
          * 2. Prefer the stronger bulk cipher, in the order of AES_256(GCM),
-         *    AES_128(GCM), AES_256, AES_128, 3DES-EDE, RC-4.
+         *    AES_128(GCM), AES_256, AES_128, 3DES-EDE.
          * 3. Prefer the stronger MAC algorithm, in the order of SHA384,
          *    SHA256, SHA, MD5.
          * 4. Prefer the better performance of key exchange and digital
@@ -1143,20 +1143,6 @@
         add("SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",        0x0013, --p,
             K_DHE_DSS,     B_3DES,        M_SHA,    N);
 
-        // RC-4
-        add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",         0xC007, --p,
-            K_ECDHE_ECDSA, B_RC4_128,     M_SHA,    N);
-        add("TLS_ECDHE_RSA_WITH_RC4_128_SHA",           0xC011, --p,
-            K_ECDHE_RSA,   B_RC4_128,     M_SHA,    N);
-        add("SSL_RSA_WITH_RC4_128_SHA",                 0x0005, --p,
-            K_RSA,         B_RC4_128,     M_SHA,    N);
-        add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA",          0xC002, --p,
-            K_ECDH_ECDSA,  B_RC4_128,     M_SHA,    N);
-        add("TLS_ECDH_RSA_WITH_RC4_128_SHA",            0xC00C, --p,
-            K_ECDH_RSA,    B_RC4_128,     M_SHA,    N);
-        add("SSL_RSA_WITH_RC4_128_MD5",                 0x0004, --p,
-            K_RSA,         B_RC4_128,     M_MD5,    N);
-
         // Renegotiation protection request Signalling Cipher Suite Value (SCSV)
         add("TLS_EMPTY_RENEGOTIATION_INFO_SCSV",        0x00ff, --p,
             K_SCSV,        B_NULL,        M_NULL,   T);
@@ -1206,6 +1192,20 @@
         add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",        0x001b, --p,
             K_DH_ANON,     B_3DES,        M_SHA,    N);
 
+        // RC-4
+        add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",         0xC007, --p,
+            K_ECDHE_ECDSA, B_RC4_128,     M_SHA,    N);
+        add("TLS_ECDHE_RSA_WITH_RC4_128_SHA",           0xC011, --p,
+            K_ECDHE_RSA,   B_RC4_128,     M_SHA,    N);
+        add("SSL_RSA_WITH_RC4_128_SHA",                 0x0005, --p,
+            K_RSA,         B_RC4_128,     M_SHA,    N);
+        add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA",          0xC002, --p,
+            K_ECDH_ECDSA,  B_RC4_128,     M_SHA,    N);
+        add("TLS_ECDH_RSA_WITH_RC4_128_SHA",            0xC00C, --p,
+            K_ECDH_RSA,    B_RC4_128,     M_SHA,    N);
+        add("SSL_RSA_WITH_RC4_128_MD5",                 0x0004, --p,
+            K_RSA,         B_RC4_128,     M_MD5,    N);
+
         add("TLS_ECDH_anon_WITH_RC4_128_SHA",           0xC016, --p,
             K_ECDH_ANON,   B_RC4_128,     M_SHA,    N);
         add("SSL_DH_anon_WITH_RC4_128_MD5",             0x0018, --p,
--- a/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java	Wed Jul 15 06:42:49 2015 -0700
@@ -542,7 +542,7 @@
                         0, clientVerifyData.length);
                 System.arraycopy(serverVerifyData, 0, verifyData,
                         clientVerifyData.length, serverVerifyData.length);
-                if (!Arrays.equals(verifyData,
+                if (!MessageDigest.isEqual(verifyData,
                                 serverHelloRI.getRenegotiatedConnection())) {
                     fatalSE(Alerts.alert_handshake_failure,
                         "Incorrect verify data in ServerHello " +
@@ -723,6 +723,14 @@
             // NOTREACHED
         }
         ephemeralServerKey = mesg.getPublicKey();
+
+        // check constraints of RSA PublicKey
+        if (!algorithmConstraints.permits(
+            EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), ephemeralServerKey)) {
+
+            throw new SSLHandshakeException("RSA ServerKeyExchange " +
+                    "does not comply to algorithm constraints");
+        }
     }
 
     /*
@@ -739,6 +747,9 @@
         dh = new DHCrypt(mesg.getModulus(), mesg.getBase(),
                                             sslContext.getSecureRandom());
         serverDH = mesg.getServerPublicKey();
+
+        // check algorithm constraints
+        dh.checkConstraints(algorithmConstraints, serverDH);
     }
 
     private void serverKeyExchange(ECDH_ServerKeyExchange mesg)
@@ -749,6 +760,14 @@
         ECPublicKey key = mesg.getPublicKey();
         ecdh = new ECDHCrypt(key.getParams(), sslContext.getSecureRandom());
         ephemeralServerKey = key;
+
+        // check constraints of EC PublicKey
+        if (!algorithmConstraints.permits(
+            EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), ephemeralServerKey)) {
+
+            throw new SSLHandshakeException("ECDH ServerKeyExchange " +
+                    "does not comply to algorithm constraints");
+        }
     }
 
     /*
--- a/src/java.base/share/classes/sun/security/ssl/DHCrypt.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/security/ssl/DHCrypt.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, 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
@@ -34,6 +34,7 @@
 import javax.crypto.KeyAgreement;
 import javax.crypto.interfaces.DHPublicKey;
 import javax.crypto.spec.*;
+import java.util.EnumSet;
 
 import sun.security.util.KeyUtil;
 
@@ -216,6 +217,28 @@
         }
     }
 
+    // Check constraints of the specified DH public key.
+    void checkConstraints(AlgorithmConstraints constraints,
+            BigInteger peerPublicValue) throws SSLHandshakeException {
+
+        try {
+            KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman");
+            DHPublicKeySpec spec =
+                        new DHPublicKeySpec(peerPublicValue, modulus, base);
+            DHPublicKey publicKey = (DHPublicKey)kf.generatePublic(spec);
+
+            // check constraints of DHPublicKey
+            if (!constraints.permits(
+                    EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), publicKey)) {
+                throw new SSLHandshakeException(
+                    "DHPublicKey does not comply to algorithm constraints");
+            }
+        } catch (GeneralSecurityException gse) {
+            throw (SSLHandshakeException) new SSLHandshakeException(
+                    "Could not generate DHPublicKey").initCause(gse);
+        }
+    }
+
     // Generate and validate DHPublicKeySpec
     private DHPublicKeySpec generateDHPublicKeySpec(KeyPairGenerator kpg)
             throws GeneralSecurityException {
--- a/src/java.base/share/classes/sun/security/ssl/ECDHCrypt.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/security/ssl/ECDHCrypt.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015, 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
@@ -29,6 +29,7 @@
 import java.security.interfaces.ECPublicKey;
 import java.security.spec.*;
 
+import java.util.EnumSet;
 import javax.crypto.SecretKey;
 import javax.crypto.KeyAgreement;
 import javax.net.ssl.SSLHandshakeException;
@@ -88,8 +89,11 @@
         return publicKey;
     }
 
-    // called by ClientHandshaker with either the server's static or ephemeral public key
-    SecretKey getAgreedSecret(PublicKey peerPublicKey) throws SSLHandshakeException {
+    // called by ClientHandshaker with either the server's static or
+    // ephemeral public key
+    SecretKey getAgreedSecret(
+            PublicKey peerPublicKey) throws SSLHandshakeException {
+
         try {
             KeyAgreement ka = JsseJce.getKeyAgreement("ECDH");
             ka.init(privateKey);
@@ -102,10 +106,13 @@
     }
 
     // called by ServerHandshaker
-    SecretKey getAgreedSecret(byte[] encodedPoint) throws SSLHandshakeException {
+    SecretKey getAgreedSecret(
+            byte[] encodedPoint) throws SSLHandshakeException {
+
         try {
             ECParameterSpec params = publicKey.getParams();
-            ECPoint point = JsseJce.decodePoint(encodedPoint, params.getCurve());
+            ECPoint point =
+                    JsseJce.decodePoint(encodedPoint, params.getCurve());
             KeyFactory kf = JsseJce.getKeyFactory("EC");
             ECPublicKeySpec spec = new ECPublicKeySpec(point, params);
             PublicKey peerPublicKey = kf.generatePublic(spec);
@@ -116,4 +123,30 @@
         }
     }
 
+    // Check constraints of the specified EC public key.
+    void checkConstraints(AlgorithmConstraints constraints,
+            byte[] encodedPoint) throws SSLHandshakeException {
+
+        try {
+
+            ECParameterSpec params = publicKey.getParams();
+            ECPoint point =
+                    JsseJce.decodePoint(encodedPoint, params.getCurve());
+            ECPublicKeySpec spec = new ECPublicKeySpec(point, params);
+
+            KeyFactory kf = JsseJce.getKeyFactory("EC");
+            ECPublicKey publicKey = (ECPublicKey)kf.generatePublic(spec);
+
+            // check constraints of ECPublicKey
+            if (!constraints.permits(
+                    EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), publicKey)) {
+                throw new SSLHandshakeException(
+                    "ECPublicKey does not comply to algorithm constraints");
+            }
+        } catch (GeneralSecurityException | java.io.IOException e) {
+            throw (SSLHandshakeException) new SSLHandshakeException(
+                    "Could not generate ECPublicKey").initCause(e);
+        }
+    }
+
 }
--- a/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java	Wed Jul 15 06:42:49 2015 -0700
@@ -2040,7 +2040,7 @@
      */
     boolean verify(HandshakeHash handshakeHash, int sender, SecretKey master) {
         byte[] myFinished = getFinished(handshakeHash, sender, master);
-        return Arrays.equals(myFinished, verifyData);
+        return MessageDigest.isEqual(myFinished, verifyData);
     }
 
     /*
--- a/src/java.base/share/classes/sun/security/ssl/Handshaker.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/security/ssl/Handshaker.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, 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
@@ -87,7 +87,7 @@
     String                      identificationProtocol;
 
     // The cryptographic algorithm constraints
-    private AlgorithmConstraints    algorithmConstraints = null;
+    AlgorithmConstraints        algorithmConstraints = null;
 
     // Local supported signature and algorithms
     Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs;
--- a/src/java.base/share/classes/sun/security/ssl/SSLAlgorithmConstraints.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/security/ssl/SSLAlgorithmConstraints.java	Wed Jul 15 06:42:49 2015 -0700
@@ -34,9 +34,9 @@
 import java.security.Key;
 
 import java.util.Set;
-import java.util.HashSet;
 
 import sun.security.util.DisabledAlgorithmConstraints;
+import static sun.security.util.DisabledAlgorithmConstraints.*;
 import sun.security.ssl.CipherSuite.*;
 
 /**
@@ -46,10 +46,15 @@
  * for the syntax of the disabled algorithm string.
  */
 final class SSLAlgorithmConstraints implements AlgorithmConstraints {
+
     private final static AlgorithmConstraints tlsDisabledAlgConstraints =
-            new TLSDisabledAlgConstraints();
+            new DisabledAlgorithmConstraints(PROPERTY_TLS_DISABLED_ALGS,
+                    new SSLAlgorithmDecomposer());
+
     private final static AlgorithmConstraints x509DisabledAlgConstraints =
-            new X509DisabledAlgConstraints();
+            new DisabledAlgorithmConstraints(PROPERTY_CERTPATH_DISABLED_ALGS,
+                    new SSLAlgorithmDecomposer(true));
+
     private AlgorithmConstraints userAlgConstraints = null;
     private AlgorithmConstraints peerAlgConstraints = null;
 
@@ -266,213 +271,4 @@
             return permits(primitives, algorithm, parameters);
         }
     }
-
-    static private class BasicDisabledAlgConstraints
-            extends DisabledAlgorithmConstraints {
-        BasicDisabledAlgConstraints(String propertyName) {
-            super(propertyName);
-        }
-
-        protected Set<String> decomposes(KeyExchange keyExchange,
-                        boolean forCertPathOnly) {
-            Set<String> components = new HashSet<>();
-            switch (keyExchange) {
-                case K_NULL:
-                    if (!forCertPathOnly) {
-                        components.add("NULL");
-                    }
-                    break;
-                case K_RSA:
-                    components.add("RSA");
-                    break;
-                case K_RSA_EXPORT:
-                    components.add("RSA");
-                    components.add("RSA_EXPORT");
-                    break;
-                case K_DH_RSA:
-                    components.add("RSA");
-                    components.add("DH");
-                    components.add("DiffieHellman");
-                    components.add("DH_RSA");
-                    break;
-                case K_DH_DSS:
-                    components.add("DSA");
-                    components.add("DSS");
-                    components.add("DH");
-                    components.add("DiffieHellman");
-                    components.add("DH_DSS");
-                    break;
-                case K_DHE_DSS:
-                    components.add("DSA");
-                    components.add("DSS");
-                    components.add("DH");
-                    components.add("DHE");
-                    components.add("DiffieHellman");
-                    components.add("DHE_DSS");
-                    break;
-                case K_DHE_RSA:
-                    components.add("RSA");
-                    components.add("DH");
-                    components.add("DHE");
-                    components.add("DiffieHellman");
-                    components.add("DHE_RSA");
-                    break;
-                case K_DH_ANON:
-                    if (!forCertPathOnly) {
-                        components.add("ANON");
-                        components.add("DH");
-                        components.add("DiffieHellman");
-                        components.add("DH_ANON");
-                    }
-                    break;
-                case K_ECDH_ECDSA:
-                    components.add("ECDH");
-                    components.add("ECDSA");
-                    components.add("ECDH_ECDSA");
-                    break;
-                case K_ECDH_RSA:
-                    components.add("ECDH");
-                    components.add("RSA");
-                    components.add("ECDH_RSA");
-                    break;
-                case K_ECDHE_ECDSA:
-                    components.add("ECDHE");
-                    components.add("ECDSA");
-                    components.add("ECDHE_ECDSA");
-                    break;
-                case K_ECDHE_RSA:
-                    components.add("ECDHE");
-                    components.add("RSA");
-                    components.add("ECDHE_RSA");
-                    break;
-                case K_ECDH_ANON:
-                    if (!forCertPathOnly) {
-                        components.add("ECDH");
-                        components.add("ANON");
-                        components.add("ECDH_ANON");
-                    }
-                    break;
-                default:
-                    if (ClientKeyExchangeService.find(keyExchange.name) != null) {
-                        if (!forCertPathOnly) {
-                            components.add(keyExchange.name);
-                        }
-                    }
-                    // otherwise ignore
-            }
-
-            return components;
-        }
-
-        protected Set<String> decomposes(BulkCipher bulkCipher) {
-            Set<String> components = new HashSet<>();
-
-            if (bulkCipher.transformation != null) {
-                components.addAll(super.decomposes(bulkCipher.transformation));
-            }
-
-            return components;
-        }
-
-        protected Set<String> decomposes(MacAlg macAlg) {
-            Set<String> components = new HashSet<>();
-
-            if (macAlg == CipherSuite.MacAlg.M_MD5) {
-                components.add("MD5");
-                components.add("HmacMD5");
-            } else if (macAlg == CipherSuite.MacAlg.M_SHA) {
-                components.add("SHA1");
-                components.add("SHA-1");
-                components.add("HmacSHA1");
-            } else if (macAlg == CipherSuite.MacAlg.M_SHA256) {
-                components.add("SHA256");
-                components.add("SHA-256");
-                components.add("HmacSHA256");
-            } else if (macAlg == CipherSuite.MacAlg.M_SHA384) {
-                components.add("SHA384");
-                components.add("SHA-384");
-                components.add("HmacSHA384");
-            }
-
-            return components;
-        }
-    }
-
-    static private class TLSDisabledAlgConstraints
-            extends BasicDisabledAlgConstraints {
-
-        TLSDisabledAlgConstraints() {
-            super(DisabledAlgorithmConstraints.PROPERTY_TLS_DISABLED_ALGS);
-        }
-
-        @Override
-        protected Set<String> decomposes(String algorithm) {
-            if (algorithm.startsWith("SSL_") || algorithm.startsWith("TLS_")) {
-                CipherSuite cipherSuite = null;
-                try {
-                    cipherSuite = CipherSuite.valueOf(algorithm);
-                } catch (IllegalArgumentException iae) {
-                    // ignore: unknown or unsupported ciphersuite
-                }
-
-                if (cipherSuite != null) {
-                    Set<String> components = new HashSet<>();
-
-                    if(cipherSuite.keyExchange != null) {
-                        components.addAll(
-                            decomposes(cipherSuite.keyExchange, false));
-                    }
-
-                    if (cipherSuite.cipher != null) {
-                        components.addAll(decomposes(cipherSuite.cipher));
-                    }
-
-                    if (cipherSuite.macAlg != null) {
-                        components.addAll(decomposes(cipherSuite.macAlg));
-                    }
-
-                    return components;
-                }
-            }
-
-            return super.decomposes(algorithm);
-        }
-    }
-
-    static private class X509DisabledAlgConstraints
-            extends BasicDisabledAlgConstraints {
-
-        X509DisabledAlgConstraints() {
-            super(DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
-        }
-
-        @Override
-        protected Set<String> decomposes(String algorithm) {
-            if (algorithm.startsWith("SSL_") || algorithm.startsWith("TLS_")) {
-                CipherSuite cipherSuite = null;
-                try {
-                    cipherSuite = CipherSuite.valueOf(algorithm);
-                } catch (IllegalArgumentException iae) {
-                    // ignore: unknown or unsupported ciphersuite
-                }
-
-                if (cipherSuite != null) {
-                    Set<String> components = new HashSet<>();
-
-                    if(cipherSuite.keyExchange != null) {
-                        components.addAll(
-                            decomposes(cipherSuite.keyExchange, true));
-                    }
-
-                    // Certification path algorithm constraints do not apply
-                    // to cipherSuite.cipher and cipherSuite.macAlg.
-
-                    return components;
-                }
-            }
-
-            return super.decomposes(algorithm);
-        }
-    }
 }
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/SSLAlgorithmDecomposer.java	Wed Jul 15 06:42:49 2015 -0700
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.ssl;
+
+import java.util.HashSet;
+import java.util.Set;
+import sun.security.util.AlgorithmDecomposer;
+import static sun.security.ssl.CipherSuite.*;
+import static sun.security.ssl.CipherSuite.KeyExchange.*;
+
+/**
+ * The class decomposes standard SSL/TLS cipher suites into sub-elements.
+ */
+class SSLAlgorithmDecomposer extends AlgorithmDecomposer {
+
+    // indicates that only certification path algorithms need to be used
+    private final boolean onlyX509;
+
+    SSLAlgorithmDecomposer(boolean onlyX509) {
+        this.onlyX509 = onlyX509;
+    }
+
+    SSLAlgorithmDecomposer() {
+        this(false);
+    }
+
+    private Set<String> decomposes(CipherSuite.KeyExchange keyExchange) {
+        Set<String> components = new HashSet<>();
+        switch (keyExchange) {
+            case K_NULL:
+                if (!onlyX509) {
+                    components.add("K_NULL");
+                }
+                break;
+            case K_RSA:
+                components.add("RSA");
+                break;
+            case K_RSA_EXPORT:
+                components.add("RSA");
+                components.add("RSA_EXPORT");
+                break;
+            case K_DH_RSA:
+                components.add("RSA");
+                components.add("DH");
+                components.add("DiffieHellman");
+                components.add("DH_RSA");
+                break;
+            case K_DH_DSS:
+                components.add("DSA");
+                components.add("DSS");
+                components.add("DH");
+                components.add("DiffieHellman");
+                components.add("DH_DSS");
+                break;
+            case K_DHE_DSS:
+                components.add("DSA");
+                components.add("DSS");
+                components.add("DH");
+                components.add("DHE");
+                components.add("DiffieHellman");
+                components.add("DHE_DSS");
+                break;
+            case K_DHE_RSA:
+                components.add("RSA");
+                components.add("DH");
+                components.add("DHE");
+                components.add("DiffieHellman");
+                components.add("DHE_RSA");
+                break;
+            case K_DH_ANON:
+                if (!onlyX509) {
+                    components.add("ANON");
+                    components.add("DH");
+                    components.add("DiffieHellman");
+                    components.add("DH_ANON");
+                }
+                break;
+            case K_ECDH_ECDSA:
+                components.add("ECDH");
+                components.add("ECDSA");
+                components.add("ECDH_ECDSA");
+                break;
+            case K_ECDH_RSA:
+                components.add("ECDH");
+                components.add("RSA");
+                components.add("ECDH_RSA");
+                break;
+            case K_ECDHE_ECDSA:
+                components.add("ECDHE");
+                components.add("ECDSA");
+                components.add("ECDHE_ECDSA");
+                break;
+            case K_ECDHE_RSA:
+                components.add("ECDHE");
+                components.add("RSA");
+                components.add("ECDHE_RSA");
+                break;
+            case K_ECDH_ANON:
+                if (!onlyX509) {
+                    components.add("ECDH");
+                    components.add("ANON");
+                    components.add("ECDH_ANON");
+                }
+                break;
+            default:
+                if (ClientKeyExchangeService.find(keyExchange.name) != null) {
+                    if (!onlyX509) {
+                        components.add(keyExchange.name);
+                    }
+                }
+                // otherwise ignore
+            }
+
+        return components;
+    }
+
+    private Set<String> decomposes(CipherSuite.BulkCipher bulkCipher) {
+        Set<String> components = new HashSet<>();
+
+        if (bulkCipher.transformation != null) {
+            components.addAll(super.decompose(bulkCipher.transformation));
+        }
+
+        switch (bulkCipher) {
+            case B_NULL:
+                components.add("C_NULL");
+                break;
+            case B_RC2_40:
+                components.add("RC2_CBC_40");
+                break;
+            case B_RC4_40:
+                components.add("RC4_40");
+                break;
+            case B_RC4_128:
+                components.add("RC4_128");
+                break;
+            case B_DES_40:
+                components.add("DES40_CBC");
+                components.add("DES_CBC_40");
+                break;
+            case B_DES:
+                components.add("DES_CBC");
+                break;
+            case B_3DES:
+                components.add("3DES_EDE_CBC");
+                break;
+            case B_AES_128:
+                components.add("AES_128_CBC");
+                break;
+            case B_AES_256:
+                components.add("AES_256_CBC");
+                break;
+            case B_AES_128_GCM:
+                components.add("AES_128_GCM");
+                break;
+            case B_AES_256_GCM:
+                components.add("AES_256_GCM");
+                break;
+        }
+
+        return components;
+    }
+
+    private Set<String> decomposes(CipherSuite.MacAlg macAlg,
+            BulkCipher cipher) {
+        Set<String> components = new HashSet<>();
+
+        if (macAlg == CipherSuite.MacAlg.M_NULL
+                && cipher.cipherType != CipherType.AEAD_CIPHER) {
+            components.add("M_NULL");
+        } else if (macAlg == CipherSuite.MacAlg.M_MD5) {
+            components.add("MD5");
+            components.add("HmacMD5");
+        } else if (macAlg == CipherSuite.MacAlg.M_SHA) {
+            components.add("SHA1");
+            components.add("SHA-1");
+            components.add("HmacSHA1");
+        } else if (macAlg == CipherSuite.MacAlg.M_SHA256) {
+            components.add("SHA256");
+            components.add("SHA-256");
+            components.add("HmacSHA256");
+        } else if (macAlg == CipherSuite.MacAlg.M_SHA384) {
+            components.add("SHA384");
+            components.add("SHA-384");
+            components.add("HmacSHA384");
+        }
+
+        return components;
+    }
+
+    private Set<String> decompose(KeyExchange keyExchange, BulkCipher cipher,
+            MacAlg macAlg) {
+        Set<String> components = new HashSet<>();
+
+        if (keyExchange != null) {
+            components.addAll(decomposes(keyExchange));
+        }
+
+        if (onlyX509) {
+            // Certification path algorithm constraints do not apply
+            // to cipher and macAlg.
+            return components;
+        }
+
+        if (cipher != null) {
+            components.addAll(decomposes(cipher));
+        }
+
+        if (macAlg != null) {
+            components.addAll(decomposes(macAlg, cipher));
+        }
+
+        return components;
+    }
+
+    @Override
+    public Set<String> decompose(String algorithm) {
+        if (algorithm.startsWith("SSL_") || algorithm.startsWith("TLS_")) {
+            CipherSuite cipherSuite = null;
+            try {
+                cipherSuite = CipherSuite.valueOf(algorithm);
+            } catch (IllegalArgumentException iae) {
+                // ignore: unknown or unsupported ciphersuite
+            }
+
+            if (cipherSuite != null) {
+                return decompose(cipherSuite.keyExchange, cipherSuite.cipher,
+                        cipherSuite.macAlg);
+            }
+        }
+
+        return super.decompose(algorithm);
+    }
+
+}
--- a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, 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
@@ -42,6 +42,9 @@
 import javax.net.ssl.*;
 import sun.misc.ManagedLocalsThread;
 
+import sun.misc.JavaNetAccess;
+import sun.misc.SharedSecrets;
+
 /**
  * Implementation of an SSL socket.  This is a normal connection type
  * socket, implementing SSL over some lower level socket, such as TCP.
@@ -377,6 +380,15 @@
      */
     private int maximumPacketSize = 0;
 
+    /*
+     * Is the local name service trustworthy?
+     *
+     * If the local name service is not trustworthy, reverse host name
+     * resolution should not be performed for endpoint identification.
+     */
+    static final boolean trustNameService =
+            Debug.getBooleanProperty("jdk.tls.trustNameService", false);
+
     //
     // CONSTRUCTORS AND INITIALIZATION CODE
     //
@@ -2063,11 +2075,40 @@
     synchronized String getHost() {
         // Note that the host may be null or empty for localhost.
         if (host == null || host.length() == 0) {
-            host = getInetAddress().getHostName();
+            if (!trustNameService) {
+                // If the local name service is not trustworthy, reverse host
+                // name resolution should not be performed for endpoint
+                // identification.  Use the application original specified
+                // hostname or IP address instead.
+                host = getOriginalHostname(getInetAddress());
+            } else {
+                host = getInetAddress().getHostName();
+            }
         }
+
         return host;
     }
 
+    /*
+     * Get the original application specified hostname.
+     */
+    private static String getOriginalHostname(InetAddress inetAddress) {
+        /*
+         * Get the original hostname via sun.misc.SharedSecrets.
+         */
+        JavaNetAccess jna = SharedSecrets.getJavaNetAccess();
+        String originalHostname = jna.getOriginalHostName(inetAddress);
+
+        /*
+         * If no application specified hostname, use the IP address.
+         */
+        if (originalHostname == null || originalHostname.length() == 0) {
+            originalHostname = inetAddress.getHostAddress();
+        }
+
+        return originalHostname;
+    }
+
     // ONLY used by HttpsClient to setup the URI specified hostname
     //
     // Please NOTE that this method MUST be called before calling to
--- a/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, 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
@@ -32,6 +32,7 @@
 import java.security.cert.*;
 import java.security.interfaces.*;
 import java.security.spec.ECParameterSpec;
+import java.math.BigInteger;
 
 import javax.crypto.SecretKey;
 import javax.crypto.spec.SecretKeySpec;
@@ -39,6 +40,7 @@
 import javax.net.ssl.*;
 
 import sun.security.util.KeyUtil;
+import sun.security.util.LegacyAlgorithmConstraints;
 import sun.security.action.GetPropertyAction;
 import sun.security.ssl.HandshakeMessage.*;
 import sun.security.ssl.CipherSuite.*;
@@ -104,6 +106,12 @@
     // The customized ephemeral DH key size for non-exportable cipher suites.
     private static final int customizedDHKeySize;
 
+    // legacy algorithm constraints
+    private static final AlgorithmConstraints legacyAlgorithmConstraints =
+            new LegacyAlgorithmConstraints(
+                    LegacyAlgorithmConstraints.PROPERTY_TLS_LEGACY_ALGS,
+                    new SSLAlgorithmDecomposer());
+
     static {
         String property = AccessController.doPrivileged(
                     new GetPropertyAction("jdk.tls.ephemeralDHKeySize"));
@@ -400,7 +408,7 @@
                 }
 
                 // verify the client_verify_data value
-                if (!Arrays.equals(clientVerifyData,
+                if (!MessageDigest.isEqual(clientVerifyData,
                                 clientHelloRI.getRenegotiatedConnection())) {
                     fatalSE(Alerts.alert_handshake_failure,
                         "Incorrect verify data in ClientHello " +
@@ -1055,6 +1063,7 @@
             proposed = getActiveCipherSuites();
         }
 
+        List<CipherSuite> legacySuites = new ArrayList<>();
         for (CipherSuite suite : prefered.collection()) {
             if (isNegotiable(proposed, suite) == false) {
                 continue;
@@ -1066,11 +1075,24 @@
                     continue;
                 }
             }
+
+            if (!legacyAlgorithmConstraints.permits(null, suite.name, null)) {
+                legacySuites.add(suite);
+                continue;
+            }
+
             if (trySetCipherSuite(suite) == false) {
                 continue;
             }
             return;
         }
+
+        for (CipherSuite suite : legacySuites) {
+            if (trySetCipherSuite(suite)) {
+                return;
+            }
+        }
+
         fatalSE(Alerts.alert_handshake_failure, "no cipher suites in common");
     }
 
@@ -1550,7 +1572,13 @@
         if (debug != null && Debug.isOn("handshake")) {
             mesg.print(System.out);
         }
-        return dh.getAgreedSecret(mesg.getClientPublicKey(), false);
+
+        BigInteger publicKeyValue = mesg.getClientPublicKey();
+
+        // check algorithm constraints
+        dh.checkConstraints(algorithmConstraints, publicKeyValue);
+
+        return dh.getAgreedSecret(publicKeyValue, false);
     }
 
     private SecretKey clientKeyExchange(ECDHClientKeyExchange mesg)
@@ -1559,7 +1587,13 @@
         if (debug != null && Debug.isOn("handshake")) {
             mesg.print(System.out);
         }
-        return ecdh.getAgreedSecret(mesg.getEncodedPoint());
+
+        byte[] publicPoint = mesg.getEncodedPoint();
+
+        // check algorithm constraints
+        ecdh.checkConstraints(algorithmConstraints, publicPoint);
+
+        return ecdh.getAgreedSecret(publicPoint);
     }
 
     /*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/sun/security/util/AbstractAlgorithmConstraints.java	Wed Jul 15 06:42:49 2015 -0700
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.security.AccessController;
+import java.security.AlgorithmConstraints;
+import java.security.PrivilegedAction;
+import java.security.Security;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The class contains common functionality for algorithm constraints classes.
+ */
+public abstract class AbstractAlgorithmConstraints
+        implements AlgorithmConstraints {
+
+    protected final AlgorithmDecomposer decomposer;
+
+    protected AbstractAlgorithmConstraints(AlgorithmDecomposer decomposer) {
+        this.decomposer = decomposer;
+    }
+
+    // Get algorithm constraints from the specified security property.
+    private static void loadAlgorithmsMap(Map<String, String[]> algorithmsMap,
+            String propertyName) {
+        String property = AccessController.doPrivileged(
+                (PrivilegedAction<String>) () -> Security.getProperty(
+                        propertyName));
+
+        String[] algorithmsInProperty = null;
+        if (property != null && !property.isEmpty()) {
+            // remove double quote marks from beginning/end of the property
+            if (property.charAt(0) == '"'
+                    && property.charAt(property.length() - 1) == '"') {
+                property = property.substring(1, property.length() - 1);
+            }
+            algorithmsInProperty = property.split(",");
+            for (int i = 0; i < algorithmsInProperty.length;
+                    i++) {
+                algorithmsInProperty[i] = algorithmsInProperty[i].trim();
+            }
+        }
+
+        // map the disabled algorithms
+        if (algorithmsInProperty == null) {
+            algorithmsInProperty = new String[0];
+        }
+        algorithmsMap.put(propertyName, algorithmsInProperty);
+    }
+
+    static String[] getAlgorithms(Map<String, String[]> algorithmsMap,
+            String propertyName) {
+        synchronized (algorithmsMap) {
+            if (!algorithmsMap.containsKey(propertyName)) {
+                loadAlgorithmsMap(algorithmsMap, propertyName);
+            }
+
+            return algorithmsMap.get(propertyName);
+        }
+    }
+
+    static boolean checkAlgorithm(String[] algorithms, String algorithm,
+            AlgorithmDecomposer decomposer) {
+        if (algorithm == null || algorithm.length() == 0) {
+            throw new IllegalArgumentException("No algorithm name specified");
+        }
+
+        Set<String> elements = null;
+        for (String item : algorithms) {
+            if (item == null || item.isEmpty()) {
+                continue;
+            }
+
+            // check the full name
+            if (item.equalsIgnoreCase(algorithm)) {
+                return false;
+            }
+
+            // decompose the algorithm into sub-elements
+            if (elements == null) {
+                elements = decomposer.decompose(algorithm);
+            }
+
+            // check the items of the algorithm
+            for (String element : elements) {
+                if (item.equalsIgnoreCase(element)) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/sun/security/util/AlgorithmDecomposer.java	Wed Jul 15 06:42:49 2015 -0700
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+/**
+ * The class decomposes standard algorithms into sub-elements.
+ */
+public class AlgorithmDecomposer {
+
+    private static final Pattern transPattern = Pattern.compile("/");
+    private static final Pattern pattern =
+                    Pattern.compile("with|and|in", Pattern.CASE_INSENSITIVE);
+
+    /**
+     * Decompose the standard algorithm name into sub-elements.
+     * <p>
+     * For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
+     * so that we can check the "SHA1" and "RSA" algorithm constraints
+     * separately.
+     * <p>
+     * Please override the method if need to support more name pattern.
+     */
+    public Set<String> decompose(String algorithm) {
+        if (algorithm == null || algorithm.length() == 0) {
+            return new HashSet<>();
+        }
+
+        // algorithm/mode/padding
+        String[] transTockens = transPattern.split(algorithm);
+
+        Set<String> elements = new HashSet<>();
+        for (String transTocken : transTockens) {
+            if (transTocken == null || transTocken.length() == 0) {
+                continue;
+            }
+
+            // PBEWith<digest>And<encryption>
+            // PBEWith<prf>And<encryption>
+            // OAEPWith<digest>And<mgf>Padding
+            // <digest>with<encryption>
+            // <digest>with<encryption>and<mgf>
+            // <digest>with<encryption>in<format>
+            String[] tokens = pattern.split(transTocken);
+
+            for (String token : tokens) {
+                if (token == null || token.length() == 0) {
+                    continue;
+                }
+
+                elements.add(token);
+            }
+        }
+
+        // In Java standard algorithm name specification, for different
+        // purpose, the SHA-1 and SHA-2 algorithm names are different. For
+        // example, for MessageDigest, the standard name is "SHA-256", while
+        // for Signature, the digest algorithm component is "SHA256" for
+        // signature algorithm "SHA256withRSA". So we need to check both
+        // "SHA-256" and "SHA256" to make the right constraint checking.
+
+        // handle special name: SHA-1 and SHA1
+        if (elements.contains("SHA1") && !elements.contains("SHA-1")) {
+            elements.add("SHA-1");
+        }
+        if (elements.contains("SHA-1") && !elements.contains("SHA1")) {
+            elements.add("SHA1");
+        }
+
+        // handle special name: SHA-224 and SHA224
+        if (elements.contains("SHA224") && !elements.contains("SHA-224")) {
+            elements.add("SHA-224");
+        }
+        if (elements.contains("SHA-224") && !elements.contains("SHA224")) {
+            elements.add("SHA224");
+        }
+
+        // handle special name: SHA-256 and SHA256
+        if (elements.contains("SHA256") && !elements.contains("SHA-256")) {
+            elements.add("SHA-256");
+        }
+        if (elements.contains("SHA-256") && !elements.contains("SHA256")) {
+            elements.add("SHA256");
+        }
+
+        // handle special name: SHA-384 and SHA384
+        if (elements.contains("SHA384") && !elements.contains("SHA-384")) {
+            elements.add("SHA-384");
+        }
+        if (elements.contains("SHA-384") && !elements.contains("SHA384")) {
+            elements.add("SHA384");
+        }
+
+        // handle special name: SHA-512 and SHA512
+        if (elements.contains("SHA512") && !elements.contains("SHA-512")) {
+            elements.add("SHA-512");
+        }
+        if (elements.contains("SHA-512") && !elements.contains("SHA512")) {
+            elements.add("SHA512");
+        }
+
+        return elements;
+    }
+
+}
--- a/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java	Wed Jul 15 06:42:49 2015 -0700
@@ -25,15 +25,9 @@
 
 package sun.security.util;
 
-import java.security.AlgorithmConstraints;
 import java.security.CryptoPrimitive;
 import java.security.AlgorithmParameters;
-
 import java.security.Key;
-import java.security.Security;
-import java.security.PrivilegedAction;
-import java.security.AccessController;
-
 import java.util.Locale;
 import java.util.Set;
 import java.util.Collections;
@@ -49,7 +43,7 @@
  * See the "jdk.certpath.disabledAlgorithms" specification in java.security
  * for the syntax of the disabled algorithm string.
  */
-public class DisabledAlgorithmConstraints implements AlgorithmConstraints {
+public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
 
     // the known security property, jdk.certpath.disabledAlgorithms
     public final static String PROPERTY_CERTPATH_DISABLED_ALGS =
@@ -64,8 +58,8 @@
     private final static Map<String, KeySizeConstraints> keySizeConstraintsMap =
                                                             new HashMap<>();
 
-    private String[] disabledAlgorithms;
-    private KeySizeConstraints keySizeConstraints;
+    private final String[] disabledAlgorithms;
+    private final KeySizeConstraints keySizeConstraints;
 
     /**
      * Initialize algorithm constraints with the specified security property.
@@ -74,56 +68,27 @@
      *        algorithm constraints
      */
     public DisabledAlgorithmConstraints(String propertyName) {
-        // Both disabledAlgorithmsMap and keySizeConstraintsMap are
-        // synchronized with the lock of disabledAlgorithmsMap.
-        synchronized (disabledAlgorithmsMap) {
-            if(!disabledAlgorithmsMap.containsKey(propertyName)) {
-                loadDisabledAlgorithmsMap(propertyName);
-            }
+        this(propertyName, new AlgorithmDecomposer());
+    }
 
-            disabledAlgorithms = disabledAlgorithmsMap.get(propertyName);
-            keySizeConstraints = keySizeConstraintsMap.get(propertyName);
-        }
+    public DisabledAlgorithmConstraints(String propertyName,
+            AlgorithmDecomposer decomposer) {
+        super(decomposer);
+        disabledAlgorithms = getAlgorithms(disabledAlgorithmsMap, propertyName);
+        keySizeConstraints = getKeySizeConstraints(disabledAlgorithms,
+                propertyName);
     }
 
     @Override
     final public boolean permits(Set<CryptoPrimitive> primitives,
             String algorithm, AlgorithmParameters parameters) {
 
-        if (algorithm == null || algorithm.length() == 0) {
-            throw new IllegalArgumentException("No algorithm name specified");
-        }
-
         if (primitives == null || primitives.isEmpty()) {
             throw new IllegalArgumentException(
                         "No cryptographic primitive specified");
         }
 
-        Set<String> elements = null;
-        for (String disabled : disabledAlgorithms) {
-            if (disabled == null || disabled.isEmpty()) {
-                continue;
-            }
-
-            // check the full name
-            if (disabled.equalsIgnoreCase(algorithm)) {
-                return false;
-            }
-
-            // decompose the algorithm into sub-elements
-            if (elements == null) {
-                elements = decomposes(algorithm);
-            }
-
-            // check the items of the algorithm
-            for (String element : elements) {
-                if (disabled.equalsIgnoreCase(element)) {
-                    return false;
-                }
-            }
-        }
-
-        return true;
+        return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
     }
 
     @Override
@@ -142,99 +107,6 @@
         return checkConstraints(primitives, algorithm, key, parameters);
     }
 
-    /**
-     * Decompose the standard algorithm name into sub-elements.
-     * <p>
-     * For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
-     * so that we can check the "SHA1" and "RSA" algorithm constraints
-     * separately.
-     * <p>
-     * Please override the method if need to support more name pattern.
-     */
-    protected Set<String> decomposes(String algorithm) {
-        if (algorithm == null || algorithm.length() == 0) {
-            return new HashSet<String>();
-        }
-
-        // algorithm/mode/padding
-        Pattern transPattern = Pattern.compile("/");
-        String[] transTockens = transPattern.split(algorithm);
-
-        Set<String> elements = new HashSet<String>();
-        for (String transTocken : transTockens) {
-            if (transTocken == null || transTocken.length() == 0) {
-                continue;
-            }
-
-            // PBEWith<digest>And<encryption>
-            // PBEWith<prf>And<encryption>
-            // OAEPWith<digest>And<mgf>Padding
-            // <digest>with<encryption>
-            // <digest>with<encryption>and<mgf>
-            // <digest>with<encryption>in<format>
-            Pattern pattern =
-                    Pattern.compile("with|and|in", Pattern.CASE_INSENSITIVE);
-            String[] tokens = pattern.split(transTocken);
-
-            for (String token : tokens) {
-                if (token == null || token.length() == 0) {
-                    continue;
-                }
-
-                elements.add(token);
-            }
-        }
-
-        // In Java standard algorithm name specification, for different
-        // purpose, the SHA-1 and SHA-2 algorithm names are different. For
-        // example, for MessageDigest, the standard name is "SHA-256", while
-        // for Signature, the digest algorithm component is "SHA256" for
-        // signature algorithm "SHA256withRSA". So we need to check both
-        // "SHA-256" and "SHA256" to make the right constraint checking.
-
-        // handle special name: SHA-1 and SHA1
-        if (elements.contains("SHA1") && !elements.contains("SHA-1")) {
-            elements.add("SHA-1");
-        }
-        if (elements.contains("SHA-1") && !elements.contains("SHA1")) {
-            elements.add("SHA1");
-        }
-
-        // handle special name: SHA-224 and SHA224
-        if (elements.contains("SHA224") && !elements.contains("SHA-224")) {
-            elements.add("SHA-224");
-        }
-        if (elements.contains("SHA-224") && !elements.contains("SHA224")) {
-            elements.add("SHA224");
-        }
-
-        // handle special name: SHA-256 and SHA256
-        if (elements.contains("SHA256") && !elements.contains("SHA-256")) {
-            elements.add("SHA-256");
-        }
-        if (elements.contains("SHA-256") && !elements.contains("SHA256")) {
-            elements.add("SHA256");
-        }
-
-        // handle special name: SHA-384 and SHA384
-        if (elements.contains("SHA384") && !elements.contains("SHA-384")) {
-            elements.add("SHA-384");
-        }
-        if (elements.contains("SHA-384") && !elements.contains("SHA384")) {
-            elements.add("SHA384");
-        }
-
-        // handle special name: SHA-512 and SHA512
-        if (elements.contains("SHA512") && !elements.contains("SHA-512")) {
-            elements.add("SHA-512");
-        }
-        if (elements.contains("SHA-512") && !elements.contains("SHA512")) {
-            elements.add("SHA512");
-        }
-
-        return elements;
-    }
-
     // Check algorithm constraints
     private boolean checkConstraints(Set<CryptoPrimitive> primitives,
             String algorithm, Key key, AlgorithmParameters parameters) {
@@ -264,43 +136,18 @@
         return true;
     }
 
-    // Get disabled algorithm constraints from the specified security property.
-    private static void loadDisabledAlgorithmsMap(
-            final String propertyName) {
-
-        String property = AccessController.doPrivileged(
-            new PrivilegedAction<String>() {
-                public String run() {
-                    return Security.getProperty(propertyName);
-                }
-            });
-
-        String[] algorithmsInProperty = null;
-
-        if (property != null && !property.isEmpty()) {
-
-            // remove double quote marks from beginning/end of the property
-            if (property.charAt(0) == '"' &&
-                    property.charAt(property.length() - 1) == '"') {
-                property = property.substring(1, property.length() - 1);
+    private static KeySizeConstraints getKeySizeConstraints(
+            String[] disabledAlgorithms, String propertyName) {
+        synchronized (keySizeConstraintsMap) {
+            if(!keySizeConstraintsMap.containsKey(propertyName)) {
+                // map the key constraints
+                KeySizeConstraints keySizeConstraints =
+                        new KeySizeConstraints(disabledAlgorithms);
+                keySizeConstraintsMap.put(propertyName, keySizeConstraints);
             }
 
-            algorithmsInProperty = property.split(",");
-            for (int i = 0; i < algorithmsInProperty.length; i++) {
-                algorithmsInProperty[i] = algorithmsInProperty[i].trim();
-            }
+            return keySizeConstraintsMap.get(propertyName);
         }
-
-        // map the disabled algorithms
-        if (algorithmsInProperty == null) {
-            algorithmsInProperty = new String[0];
-        }
-        disabledAlgorithmsMap.put(propertyName, algorithmsInProperty);
-
-        // map the key constraints
-        KeySizeConstraints keySizeConstraints =
-            new KeySizeConstraints(algorithmsInProperty);
-        keySizeConstraintsMap.put(propertyName, keySizeConstraints);
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/sun/security/util/LegacyAlgorithmConstraints.java	Wed Jul 15 06:42:49 2015 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.security.AlgorithmParameters;
+import java.security.CryptoPrimitive;
+import java.security.Key;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import static sun.security.util.AbstractAlgorithmConstraints.getAlgorithms;
+
+/**
+ * Algorithm constraints for legacy algorithms.
+ */
+public class LegacyAlgorithmConstraints extends AbstractAlgorithmConstraints {
+
+    // the known security property, jdk.tls.legacyAlgorithms
+    public final static String PROPERTY_TLS_LEGACY_ALGS =
+            "jdk.tls.legacyAlgorithms";
+
+    private final static Map<String, String[]> legacyAlgorithmsMap =
+                                                          new HashMap<>();
+
+    private final String[] legacyAlgorithms;
+
+    public LegacyAlgorithmConstraints(String propertyName,
+            AlgorithmDecomposer decomposer) {
+        super(decomposer);
+        legacyAlgorithms = getAlgorithms(legacyAlgorithmsMap, propertyName);
+    }
+
+    @Override
+    final public boolean permits(Set<CryptoPrimitive> primitives,
+            String algorithm, AlgorithmParameters parameters) {
+        return checkAlgorithm(legacyAlgorithms, algorithm, decomposer);
+    }
+
+    @Override
+    final public boolean permits(Set<CryptoPrimitive> primitives, Key key) {
+        return true;
+    }
+
+    @Override
+    final public boolean permits(Set<CryptoPrimitive> primitives,
+            String algorithm, Key key, AlgorithmParameters parameters) {
+        return checkAlgorithm(legacyAlgorithms, algorithm, decomposer);
+    }
+
+}
--- a/src/java.base/share/classes/sun/security/validator/SimpleValidator.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/classes/sun/security/validator/SimpleValidator.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, 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
@@ -141,8 +141,18 @@
         // create distrusted certificates checker
         UntrustedChecker untrustedChecker = new UntrustedChecker();
 
+        // check if anchor is untrusted
+        X509Certificate anchorCert = chain[chain.length - 1];
+        try {
+            untrustedChecker.check(anchorCert);
+        } catch (CertPathValidatorException cpve) {
+            throw new ValidatorException(
+                "Untrusted certificate: "+ anchorCert.getSubjectX500Principal(),
+                ValidatorException.T_UNTRUSTED_CERT, anchorCert, cpve);
+        }
+
         // create default algorithm constraints checker
-        TrustAnchor anchor = new TrustAnchor(chain[chain.length - 1], null);
+        TrustAnchor anchor = new TrustAnchor(anchorCert, null);
         AlgorithmChecker defaultAlgChecker = new AlgorithmChecker(anchor);
 
         // create application level algorithm constraints checker
--- a/src/java.base/share/conf/security/java.security	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/share/conf/security/java.security	Wed Jul 15 06:42:49 2015 -0700
@@ -541,4 +541,61 @@
 #
 # Example:
 #   jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
-jdk.tls.disabledAlgorithms=SSLv3, RC4
+jdk.tls.disabledAlgorithms=SSLv3, RC4, DH keySize < 768
+
+# Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
+# processing in JSSE implementation.
+#
+# In some environments, a certain algorithm may be undesirable but it
+# cannot be disabled because of its use in legacy applications.  Legacy
+# algorithms may still be supported, but applications should not use them
+# as the security strength of legacy algorithms are usually not strong enough
+# in practice.
+#
+# During SSL/TLS security parameters negotiation, legacy algorithms will
+# not be negotiated unless there are no other candidates.
+#
+# The syntax of the disabled algorithm string is described as this Java
+# BNF-style:
+#   LegacyAlgorithms:
+#       " LegacyAlgorithm { , LegacyAlgorithm } "
+#
+#   LegacyAlgorithm:
+#       AlgorithmName (standard JSSE algorithm name)
+#
+# See the specification of security property "jdk.certpath.disabledAlgorithms"
+# for the syntax and description of the "AlgorithmName" notation.
+#
+# Per SSL/TLS specifications, cipher suites have the form:
+#       SSL_KeyExchangeAlg_WITH_CipherAlg_MacAlg
+# or
+#       TLS_KeyExchangeAlg_WITH_CipherAlg_MacAlg
+#
+# For example, the cipher suite TLS_RSA_WITH_AES_128_CBC_SHA uses RSA as the
+# key exchange algorithm, AES_128_CBC (128 bits AES cipher algorithm in CBC
+# mode) as the cipher (encryption) algorithm, and SHA-1 as the message digest
+# algorithm for HMAC.
+#
+# The LegacyAlgorithm can be one of the following standard algorithm names:
+#     1. JSSE cipher suite name, e.g., TLS_RSA_WITH_AES_128_CBC_SHA
+#     2. JSSE key exchange algorithm name, e.g., RSA
+#     3. JSSE cipher (encryption) algorithm name, e.g., AES_128_CBC
+#     4. JSSE message digest algorithm name, e.g., SHA
+#
+# See SSL/TLS specifications and "Java Cryptography Architecture Standard
+# Algorithm Name Documentation" for information about the algorithm names.
+#
+# Note: This property is currently used by Oracle's JSSE implementation.
+# It is not guaranteed to be examined and used by other implementations.
+# There is no guarantee the property will continue to exist or be of the
+# same syntax in future releases.
+#
+# Example:
+#   jdk.tls.legacyAlgorithms=DH_anon, DES_CBC, SSL_RSA_WITH_RC4_128_MD5
+#
+jdk.tls.legacyAlgorithms= \
+        K_NULL, C_NULL, M_NULL, \
+        DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \
+        DH_RSA_EXPORT, RSA_EXPORT, \
+        DH_anon, ECDH_anon, \
+        RC4_128, RC4_40, DES_CBC, DES40_CBC
--- a/src/java.base/unix/native/libjli/java_md_solinux.c	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/unix/native/libjli/java_md_solinux.c	Wed Jul 15 06:42:49 2015 -0700
@@ -340,6 +340,7 @@
       char* newpath     = NULL; /* path on new LD_LIBRARY_PATH */
       char* lastslash   = NULL;
       char** newenvp    = NULL; /* current environment */
+      size_t new_runpath_size;
 #ifdef __solaris__
       char*  dmpath     = NULL;  /* data model specific LD_LIBRARY_PATH,
                                     Solaris only */
@@ -516,13 +517,14 @@
             /* runpath contains current effective LD_LIBRARY_PATH setting */
 
             jvmpath = JLI_StringDup(jvmpath);
-            new_runpath = JLI_MemAlloc(((runpath != NULL) ? JLI_StrLen(runpath) : 0) +
+            new_runpath_size = ((runpath != NULL) ? JLI_StrLen(runpath) : 0) +
                     2 * JLI_StrLen(jrepath) + 2 * JLI_StrLen(arch) +
 #ifdef AIX
                     /* On AIX we additionally need 'jli' in the path because ld doesn't support $ORIGIN. */
                     JLI_StrLen(jrepath) + JLI_StrLen(arch) + JLI_StrLen("/lib//jli:") +
 #endif
-                    JLI_StrLen(jvmpath) + 52);
+                    JLI_StrLen(jvmpath) + 52;
+            new_runpath = JLI_MemAlloc(new_runpath_size);
             newpath = new_runpath + JLI_StrLen(LD_LIBRARY_PATH "=");
 
 
@@ -577,6 +579,11 @@
              * loop of execv() because we test for the prefix, above.
              */
             if (runpath != 0) {
+                /* ensure storage for runpath + colon + NULL */
+                if ((JLI_StrLen(runpath) + 1 + 1) > new_runpath_size) {
+                    JLI_ReportErrorMessageSys(JRE_ERROR11);
+                    exit(1);
+                }
                 JLI_StrCat(new_runpath, ":");
                 JLI_StrCat(new_runpath, runpath);
             }
@@ -667,7 +674,11 @@
             JLI_TraceLauncher("JRE path is %s\n", path);
             return JNI_TRUE;
         }
-
+        /* ensure storage for path + /jre + NULL */
+        if ((JLI_StrLen(path) + 4  + 1) > (size_t) pathsize) {
+            JLI_TraceLauncher("Insufficient space to store JRE path\n");
+            return JNI_FALSE;
+        }
         /* Does the app ship a private JRE in <apphome>/jre directory? */
         JLI_Snprintf(libjava, sizeof(libjava), "%s/jre/lib/%s/" JAVA_DLL, path, arch);
         if (access(libjava, F_OK) == 0) {
--- a/src/java.base/unix/native/libnet/net_util_md.c	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/unix/native/libnet/net_util_md.c	Wed Jul 15 06:42:49 2015 -0700
@@ -1524,6 +1524,7 @@
     int exclbind = -1;
 #endif
     int rv;
+    int arg, alen;
 
 #ifdef __linux__
     /*
@@ -1540,7 +1541,7 @@
     }
 #endif
 
-#if defined(__solaris__) && defined(AF_INET6)
+#if defined(__solaris__)
     /*
      * Solaris has separate IPv4 and IPv6 port spaces so we
      * use an exclusive bind when SO_REUSEADDR is not used to
@@ -1550,35 +1551,31 @@
      * results in a late bind that fails because the
      * corresponding IPv4 port is in use.
      */
-    if (ipv6_available()) {
-        int arg;
-        socklen_t len;
+    alen = sizeof(arg);
 
-        len = sizeof(arg);
-        if (useExclBind || getsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
-                       (char *)&arg, &len) == 0) {
-            if (useExclBind || arg == 0) {
-                /*
-                 * SO_REUSEADDR is disabled or sun.net.useExclusiveBind
-                 * property is true so enable TCP_EXCLBIND or
-                 * UDP_EXCLBIND
-                 */
-                len = sizeof(arg);
-                if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&arg,
-                               &len) == 0) {
-                    if (arg == SOCK_STREAM) {
-                        level = IPPROTO_TCP;
-                        exclbind = TCP_EXCLBIND;
-                    } else {
-                        level = IPPROTO_UDP;
-                        exclbind = UDP_EXCLBIND;
-                    }
+    if (useExclBind || getsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
+                   (char *)&arg, &alen) == 0) {
+        if (useExclBind || arg == 0) {
+            /*
+             * SO_REUSEADDR is disabled or sun.net.useExclusiveBind
+             * property is true so enable TCP_EXCLBIND or
+             * UDP_EXCLBIND
+             */
+            alen = sizeof(arg);
+            if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&arg,
+                           &alen) == 0) {
+                if (arg == SOCK_STREAM) {
+                    level = IPPROTO_TCP;
+                    exclbind = TCP_EXCLBIND;
+                } else {
+                    level = IPPROTO_UDP;
+                    exclbind = UDP_EXCLBIND;
                 }
+            }
 
-                arg = 1;
-                setsockopt(fd, level, exclbind, (char *)&arg,
-                           sizeof(arg));
-            }
+            arg = 1;
+            setsockopt(fd, level, exclbind, (char *)&arg,
+                       sizeof(arg));
         }
     }
 
--- a/src/java.base/windows/native/libjli/java_md.c	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.base/windows/native/libjli/java_md.c	Wed Jul 15 06:42:49 2015 -0700
@@ -323,7 +323,11 @@
             JLI_TraceLauncher("JRE path is %s\n", path);
             return JNI_TRUE;
         }
-
+        /* ensure storage for path + \jre + NULL */
+        if ((JLI_StrLen(path) + 4 + 1) > (size_t) pathsize) {
+            JLI_TraceLauncher("Insufficient space to store JRE path\n");
+            return JNI_FALSE;
+        }
         /* Does this app ship a private JRE in <apphome>\jre directory? */
         JLI_Snprintf(javadll, sizeof (javadll), "%s\\jre\\bin\\" JAVA_DLL, path);
         if (stat(javadll, &s) == 0) {
--- a/src/java.desktop/share/classes/sun/awt/SunToolkit.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/classes/sun/awt/SunToolkit.java	Wed Jul 15 06:42:49 2015 -0700
@@ -66,6 +66,7 @@
 import sun.awt.image.URLImageSource;
 import sun.font.FontDesignMetrics;
 import sun.misc.SoftCache;
+import sun.net.util.URLUtil;
 import sun.security.action.GetBooleanAction;
 import sun.security.action.GetPropertyAction;
 import sun.util.logging.PlatformLogger;
@@ -875,7 +876,7 @@
         if (sm != null) {
             try {
                 java.security.Permission perm =
-                    url.openConnection().getPermission();
+                    URLUtil.getConnectPermission(url);
                 if (perm != null) {
                     try {
                         sm.checkPermission(perm);
--- a/src/java.desktop/share/classes/sun/awt/image/URLImageSource.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/classes/sun/awt/image/URLImageSource.java	Wed Jul 15 06:42:49 2015 -0700
@@ -31,6 +31,7 @@
 import java.net.URL;
 import java.net.URLConnection;
 import java.net.MalformedURLException;
+import sun.net.util.URLUtil;
 
 public class URLImageSource extends InputStreamImageSource {
     URL url;
@@ -43,7 +44,7 @@
         if (sm != null) {
             try {
                 java.security.Permission perm =
-                    u.openConnection().getPermission();
+                      URLUtil.getConnectPermission(u);
                 if (perm != null) {
                     try {
                         sm.checkPermission(perm);
--- a/src/java.desktop/share/native/libfontmanager/layout/AlternateSubstSubtables.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/AlternateSubstSubtables.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -53,6 +53,7 @@
             Offset alternateSetTableOffset = SWAPW(alternateSetTableOffsetArray[coverageIndex]);
             const LEReferenceTo<AlternateSetTable> alternateSetTable(base, success,
                                   (const AlternateSetTable *) ((char *) this + alternateSetTableOffset));
+            if (!LE_SUCCESS(success)) return 0;
             TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[0]);
 
             if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate), success)) {
--- a/src/java.desktop/share/native/libfontmanager/layout/AnchorTables.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/AnchorTables.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -44,21 +44,27 @@
     case 1:
     {
         LEReferenceTo<Format1AnchorTable> f1(base, success);
-        f1->getAnchor(f1, fontInstance, anchor, success);
+        if (LE_SUCCESS(success)) {
+            f1->getAnchor(f1, fontInstance, anchor, success);
+        }
         break;
     }
 
     case 2:
     {
         LEReferenceTo<Format2AnchorTable> f2(base, success);
-        f2->getAnchor(f2, glyphID, fontInstance, anchor, success);
+        if (LE_SUCCESS(success)) {
+            f2->getAnchor(f2, glyphID, fontInstance, anchor, success);
+        }
         break;
     }
 
     case 3:
     {
         LEReferenceTo<Format3AnchorTable> f3(base, success);
-        f3->getAnchor(f3, fontInstance, anchor, success);
+        if (LE_SUCCESS(success)) {
+            f3->getAnchor(f3, fontInstance, anchor, success);
+        }
         break;
     }
 
@@ -66,7 +72,9 @@
     {
         // unknown format: just use x, y coordinate, like format 1...
         LEReferenceTo<Format1AnchorTable> f1(base, success);
-        f1->getAnchor(f1, fontInstance, anchor, success);
+        if (LE_SUCCESS(success)) {
+            f1->getAnchor(f1, fontInstance, anchor, success);
+        }
         break;
     }
   }
@@ -112,16 +120,18 @@
 
     if (dtxOffset != 0) {
         LEReferenceTo<DeviceTable> dt(base, success, dtxOffset);
-        le_int16 adjx = dt->getAdjustment(dt, (le_int16) fontInstance->getXPixelsPerEm(), success);
-
-        pixels.fX += adjx;
+        if (LE_SUCCESS(success)) {
+            le_int16 adjx = dt->getAdjustment(dt, (le_int16) fontInstance->getXPixelsPerEm(), success);
+            pixels.fX += adjx;
+        }
     }
 
     if (dtyOffset != 0) {
         LEReferenceTo<DeviceTable> dt(base, success, dtyOffset);
-        le_int16 adjy = dt->getAdjustment(dt, (le_int16) fontInstance->getYPixelsPerEm(), success);
-
-        pixels.fY += adjy;
+        if (LE_SUCCESS(success)) {
+            le_int16 adjy = dt->getAdjustment(dt, (le_int16) fontInstance->getYPixelsPerEm(), success);
+            pixels.fY += adjy;
+        }
     }
 
     fontInstance->pixelsToUnits(pixels, anchor);
--- a/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphInsertionProc2.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphInsertionProc2.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -107,6 +107,10 @@
 
     le_int16 markIndex = SWAPW(entry->markedInsertionListIndex);
     if (markIndex > 0) {
+        if (markGlyph < 0 || markGlyph >= glyphStorage.getGlyphCount()) {
+           success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+           return 0;
+        }
         le_int16 count = (flags & cgiMarkedInsertCountMask) >> 5;
         le_bool isKashidaLike = (flags & cgiMarkedIsKashidaLike);
         le_bool isBefore = (flags & cgiMarkInsertBefore);
@@ -115,6 +119,10 @@
 
     le_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
     if (currIndex > 0) {
+        if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
+           success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+           return 0;
+        }
         le_int16 count = flags & cgiCurrentInsertCountMask;
         le_bool isKashidaLike = (flags & cgiCurrentIsKashidaLike);
         le_bool isBefore = (flags & cgiCurrentInsertBefore);
--- a/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -76,6 +76,10 @@
   WordOffset currOffset = SWAPW(entry->currOffset);
 
   if (markOffset != 0 && LE_SUCCESS(success)) {
+    if (markGlyph < 0 || markGlyph >= glyphStorage.getGlyphCount()) {
+       success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+       return 0;
+    }
     LEGlyphID mGlyph = glyphStorage[markGlyph];
     TTGlyphID newGlyph = SWAPW(int16Table.getObject(markOffset + LE_GET_GLYPH(mGlyph), success)); // whew.
 
@@ -83,6 +87,10 @@
   }
 
   if (currOffset != 0) {
+    if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
+       success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+       return 0;
+    }
     LEGlyphID thisGlyph = glyphStorage[currGlyph];
     TTGlyphID newGlyph = SWAPW(int16Table.getObject(currOffset + LE_GET_GLYPH(thisGlyph), success)); // whew.
 
--- a/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc2.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc2.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -70,17 +70,25 @@
     if(LE_FAILURE(success)) return 0;
     le_uint16 newState = SWAPW(entry->newStateIndex);
     le_uint16 flags = SWAPW(entry->flags);
-    le_int16 markIndex = SWAPW(entry->markIndex);
-    le_int16 currIndex = SWAPW(entry->currIndex);
+    le_uint16 markIndex = SWAPW(entry->markIndex);
+    le_uint16 currIndex = SWAPW(entry->currIndex);
 
-    if (markIndex != -1) {
+    if (markIndex != 0x0FFFF) {
+        if (markGlyph < 0 || markGlyph >= glyphStorage.getGlyphCount()) {
+           success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+           return 0;
+        }
         le_uint32 offset = SWAPL(perGlyphTable(markIndex, success));
         LEGlyphID mGlyph = glyphStorage[markGlyph];
         TTGlyphID newGlyph = lookup(offset, mGlyph, success);
         glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
     }
 
-    if (currIndex != -1) {
+    if (currIndex != 0x0FFFF) {
+        if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
+           success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+           return 0;
+        }
         le_uint32 offset = SWAPL(perGlyphTable(currIndex, success));
         LEGlyphID thisGlyph = glyphStorage[currGlyph];
         TTGlyphID newGlyph = lookup(offset, thisGlyph, success);
--- a/src/java.desktop/share/native/libfontmanager/layout/Features.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/Features.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -41,7 +41,7 @@
 LEReferenceTo<FeatureTable> FeatureListTable::getFeatureTable(const LETableReference &base, le_uint16 featureIndex, LETag *featureTag, LEErrorCode &success) const
 {
     LEReferenceToArrayOf<FeatureRecord>
-        featureRecordArrayRef(base, success, featureRecordArray, featureIndex);
+        featureRecordArrayRef(base, success, featureRecordArray, featureIndex+1);
 
   if (featureIndex >= SWAPW(featureCount) || LE_FAILURE(success)) {
     return LEReferenceTo<FeatureTable>();
--- a/src/java.desktop/share/native/libfontmanager/layout/GXLayoutEngine.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/GXLayoutEngine.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -73,7 +73,7 @@
 
     fMorphTable->process(fMorphTable, glyphStorage, success);
 
-    return count;
+    return glyphStorage.getGlyphCount();
 }
 
 // apply positional tables
--- a/src/java.desktop/share/native/libfontmanager/layout/GXLayoutEngine2.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/GXLayoutEngine2.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -69,7 +69,7 @@
     }
 
     fMorphTable->process(fMorphTable, glyphStorage, fTypoFlags, success);
-    return count;
+    return glyphStorage.getGlyphCount();
 }
 
 // apply positional tables
--- a/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -70,6 +70,11 @@
     ByteOffset newState = SWAPW(entry->newStateOffset);
     IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
 
+    if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
+       success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+       return 0;
+    }
+
     if (flags & irfMarkFirst) {
         firstGlyph = currGlyph;
     }
--- a/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor2.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor2.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -68,6 +68,11 @@
     le_uint16 newState = SWAPW(entry->newStateIndex); // index to the new state
     IndicRearrangementFlags  flags =  (IndicRearrangementFlags) SWAPW(entry->flags);
 
+    if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
+       success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+       return 0;
+    }
+
     if (flags & irfMarkFirst) {
         firstGlyph = currGlyph;
     }
--- a/src/java.desktop/share/native/libfontmanager/layout/LETableReference.h	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/LETableReference.h	Wed Jul 15 06:42:49 2015 -0700
@@ -188,7 +188,7 @@
 
   void addOffset(size_t offset, LEErrorCode &success) {
     if(hasBounds()) {
-      if(offset > fLength) {
+      if(offset >= fLength) {
         LE_DEBUG_TR("addOffset off end");
         success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
         return;
@@ -203,7 +203,7 @@
     if(atPtr==NULL) return 0;
     if(LE_FAILURE(success)) return LE_UINTPTR_MAX;
     if((atPtr < fStart) ||
-       (hasBounds() && (atPtr > fStart+fLength))) {
+       (hasBounds() && (atPtr >= fStart+fLength))) {
       LE_DEBUG_TR3("ptrToOffset args out of range: %p", atPtr, 0);
       success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
       return LE_UINTPTR_MAX;
@@ -240,6 +240,18 @@
   }
 
   /**
+  * Throw an error if size*count overflows
+  */
+  size_t verifyLength(size_t offset, size_t size, le_uint32 count, LEErrorCode &success) {
+    if(count!=0 && size>LE_UINT32_MAX/count) {
+      LE_DEBUG_TR3("verifyLength failed size=%u, count=%u", size, count);
+      success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+      return 0;
+    }
+    return verifyLength(offset, size*count, success);
+  }
+
+  /**
    * Change parent link to another
    */
   LETableReference &reparent(const LETableReference &base) {
@@ -424,7 +436,7 @@
       if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
         fCount = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
       }
-      LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*fCount, success);
+      LETableReference::verifyLength(0, LETableVarSizer<T>::getSize(), fCount, success);
     }
     if(LE_FAILURE(success)) {
       fCount=0;
@@ -439,7 +451,7 @@
       if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
         fCount = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
       }
-      LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*fCount, success);
+      LETableReference::verifyLength(0, LETableVarSizer<T>::getSize(), fCount, success);
     }
     if(LE_FAILURE(success)) clear();
   }
@@ -450,7 +462,7 @@
       if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
         fCount = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
       }
-      LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*fCount, success);
+      LETableReference::verifyLength(0, LETableVarSizer<T>::getSize(), fCount, success);
     }
     if(LE_FAILURE(success)) clear();
   }
--- a/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -73,7 +73,7 @@
   const LigatureSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
 
     ByteOffset newState = SWAPW(entry->newStateOffset);
-    le_int16 flags = SWAPW(entry->flags);
+    le_uint16 flags = SWAPW(entry->flags);
 
     if (flags & lsfSetComponent) {
         if (++m >= nComponents) {
@@ -92,15 +92,18 @@
     if (actionOffset != 0) {
       LEReferenceTo<LigatureActionEntry> ap(stHeader, success, actionOffset);
         LigatureActionEntry action;
-        le_int32 offset, i = 0;
+        le_int32 offset, i = 0, j = 0;
         le_int32 stack[nComponents];
         le_int16 mm = -1;
 
         do {
             le_uint32 componentGlyph = componentStack[m--];
 
+            if (j++ > 0) {
+                ap.addObject(success);
+            }
+
             action = SWAPL(*ap.getAlias());
-            ap.addObject(success); // ap++
 
             if (m < 0) {
                 m = nComponents - 1;
--- a/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc2.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc2.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -98,7 +98,7 @@
         ap.addObject(ligActionIndex, success);
         LEReferenceToArrayOf<TTGlyphID> ligatureTable(stHeader, success, ligatureOffset, LE_UNBOUNDED_ARRAY);
         LigatureActionEntry action;
-        le_int32 offset, i = 0;
+        le_int32 offset, i = 0, j = 0;
         le_int32 stack[nComponents];
         le_int16 mm = -1;
 
@@ -111,6 +111,10 @@
         do {
             le_uint32 componentGlyph = componentStack[m--]; // pop off
 
+            if (j++ > 0) {
+                ap.addObject(success);
+            }
+
             action = SWAPL(*ap.getAlias());
 
             if (m < 0) {
@@ -144,7 +148,6 @@
               LE_DEBUG_BAD_FONT("m<0")
             }
 #endif
-            ap.addObject(success);
         } while (LE_SUCCESS(success) && !(action & lafLast) && (m>=0) ); // stop if last bit is set, or if run out of items
 
         while (mm >= 0) {
--- a/src/java.desktop/share/native/libfontmanager/layout/MarkToBasePosnSubtables.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/MarkToBasePosnSubtables.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -97,13 +97,9 @@
 
     if( LE_FAILURE(success) ) { return 0; }
     Offset anchorTableOffset = SWAPW(baseRecord->baseAnchorTableOffsetArray[markClass]);
-    if (anchorTableOffset <= 0) {
-        // this means the table is mal-formed...
-        glyphIterator->setCurrGlyphBaseOffset(baseIterator.getCurrStreamPosition());
-        return 0;
-    }
+    LEReferenceTo<AnchorTable> anchorTable(baseArray, success, anchorTableOffset);
+    if( LE_FAILURE(success) ) { return 0; }
 
-    LEReferenceTo<AnchorTable> anchorTable(baseArray, success, anchorTableOffset);
     LEPoint baseAnchor, markAdvance, pixels;
 
 
--- a/src/java.desktop/share/native/libfontmanager/layout/MorphTables.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/MorphTables.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -52,8 +52,15 @@
     le_uint32 chain;
 
     for (chain = 0; LE_SUCCESS(success) && (chain < chainCount); chain += 1) {
+        if (chain > 0) {
+            le_uint32 chainLength = SWAPL(chainHeader->chainLength);
+            if (chainLength & 0x03) { // incorrect alignment for 32 bit tables
+                success = LE_MEMORY_ALLOCATION_ERROR; // as good a choice as any
+                return;
+            }
+            chainHeader.addOffset(chainLength, success);
+        }
         FeatureFlags defaultFlags = SWAPL(chainHeader->defaultFlags);
-        le_uint32 chainLength = SWAPL(chainHeader->chainLength);
         le_int16 nFeatureEntries = SWAPW(chainHeader->nFeatureEntries);
         le_int16 nSubtables = SWAPW(chainHeader->nSubtables);
         LEReferenceTo<MorphSubtableHeader> subtableHeader =
@@ -61,7 +68,14 @@
         le_int16 subtable;
 
         for (subtable = 0; LE_SUCCESS(success) && (subtable < nSubtables); subtable += 1) {
-            le_int16 length = SWAPW(subtableHeader->length);
+            if (subtable > 0) {
+                le_int16 length = SWAPW(subtableHeader->length);
+                if (length & 0x03) { // incorrect alignment for 32 bit tables
+                    success = LE_MEMORY_ALLOCATION_ERROR; // as good a choice as any
+                    return;
+                }
+                subtableHeader.addOffset(length, success);
+            }
             SubtableCoverage coverage = SWAPW(subtableHeader->coverage);
             FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
 
@@ -69,10 +83,7 @@
             if ((coverage & scfVertical) == 0 && (subtableFeatures & defaultFlags) != 0  && LE_SUCCESS(success)) {
               subtableHeader->process(subtableHeader, glyphStorage, success);
             }
-
-            subtableHeader.addOffset(length, success);
         }
-        chainHeader.addOffset(chainLength, success);
     }
 }
 
--- a/src/java.desktop/share/native/libfontmanager/layout/MorphTables2.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/MorphTables2.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -59,6 +59,10 @@
   for (chain = 0; LE_SUCCESS(success) && (chain < chainCount); chain++) {
         if (chain>0) {
           le_uint32 chainLength = SWAPL(chainHeader->chainLength);
+          if (chainLength & 0x03) { // incorrect alignment for 32 bit tables
+              success = LE_MEMORY_ALLOCATION_ERROR; // as good a choice as any
+              return;
+          }
           chainHeader.addOffset(chainLength, success); // Don't increment the first time
         }
         FeatureFlags flag = SWAPL(chainHeader->defaultFlags);
@@ -188,6 +192,10 @@
         for (subtable = 0;  LE_SUCCESS(success) && subtable < nSubtables; subtable++) {
             if(subtable>0)  {
               le_uint32 length = SWAPL(subtableHeader->length);
+              if (length & 0x03) { // incorrect alignment for 32 bit tables
+                  success = LE_MEMORY_ALLOCATION_ERROR; // as good a choice as any
+                  return;
+              }
               subtableHeader.addOffset(length, success); // Don't addOffset for the last entry.
             }
             le_uint32 coverage = SWAPL(subtableHeader->coverage);
--- a/src/java.desktop/share/native/libfontmanager/layout/PairPositioningSubtables.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/PairPositioningSubtables.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -179,12 +179,13 @@
         LEReferenceTo<PairValueRecord> record(records);
 
         for(le_int32 r = 0; r < recordCount; r += 1) {
+          if (r > 0) {
+            record.addOffset(recordSize, success);
+          }
           if(LE_FAILURE(success)) return LEReferenceTo<PairValueRecord>();
           if (SWAPW(record->secondGlyph) == glyphID) {
             return record;
           }
-
-          record.addOffset(recordSize, success);
         }
 #else
   #error dead code - not updated.
--- a/src/java.desktop/share/native/libfontmanager/layout/SingleSubstitutionSubtables.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/SingleSubstitutionSubtables.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -94,7 +94,9 @@
         return 0;
     }
 
-    if (coverageIndex >= 0) {
+    LEReferenceToArrayOf<TTGlyphID> substituteArrayRef(base, success, substituteArray, SWAPW(glyphCount));
+
+    if (coverageIndex >= 0 && LE_SUCCESS(success) && coverageIndex < substituteArrayRef.getCount()) {
         TTGlyphID substitute = SWAPW(substituteArray[coverageIndex]);
 
         if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, substitute), success)) {
--- a/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -85,6 +85,7 @@
         if (currGlyph == glyphCount) {
             // XXX: How do we handle EOT vs. EOL?
             classCode = classCodeEOT;
+            break;
         } else {
             TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(glyphStorage[currGlyph]);
 
--- a/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor2.cpp	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor2.cpp	Wed Jul 15 06:42:49 2015 -0700
@@ -103,6 +103,7 @@
                 if (currGlyph == glyphCount || currGlyph == -1) {
                     // XXX: How do we handle EOT vs. EOL?
                     classCode = classCodeEOT;
+                    break;
                 } else {
                     LEGlyphID gid = glyphStorage[currGlyph];
                     TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
@@ -134,6 +135,7 @@
                 if (currGlyph == glyphCount || currGlyph == -1) {
                     // XXX: How do we handle EOT vs. EOL?
                     classCode = classCodeEOT;
+                    break;
                 } else {
                     LEGlyphID gid = glyphStorage[currGlyph];
                     TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
@@ -171,6 +173,7 @@
                 if (currGlyph == glyphCount || currGlyph == -1) {
                     // XXX: How do we handle EOT vs. EOL?
                     classCode = classCodeEOT;
+                    break;
                 } else if(currGlyph > glyphCount) {
                   // note if > glyphCount, we've run off the end (bad font)
                   currGlyph = glyphCount;
@@ -211,6 +214,7 @@
                 if (currGlyph == glyphCount || currGlyph == -1) {
                     // XXX: How do we handle EOT vs. EOL?
                     classCode = classCodeEOT;
+                    break;
                 } else {
                     TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(glyphStorage[currGlyph]);
                     if (glyphCode == 0xFFFF) {
--- a/src/java.desktop/share/native/libfontmanager/layout/StateTables.h	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.desktop/share/native/libfontmanager/layout/StateTables.h	Wed Jul 15 06:42:49 2015 -0700
@@ -126,7 +126,7 @@
 struct StateEntry
 {
     ByteOffset  newStateOffset;
-    le_int16    flags;
+    le_uint16    flags;
 };
 
 typedef le_uint16 EntryTableIndex2;
--- a/src/java.management/share/classes/javax/management/MBeanServerInvocationHandler.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.management/share/classes/javax/management/MBeanServerInvocationHandler.java	Wed Jul 15 06:42:49 2015 -0700
@@ -141,6 +141,12 @@
         if (connection == null) {
             throw new IllegalArgumentException("Null connection");
         }
+        if (Proxy.isProxyClass(connection.getClass())) {
+            if (MBeanServerInvocationHandler.class.isAssignableFrom(
+                    Proxy.getInvocationHandler(connection).getClass())) {
+                throw new IllegalArgumentException("Wrapping MBeanServerInvocationHandler");
+            }
+        }
         if (objectName == null) {
             throw new IllegalArgumentException("Null object name");
         }
@@ -418,6 +424,10 @@
                              new Class<?>[] {Object.class})
             && isLocal(proxy, method))
             return true;
+        if (methodName.equals("finalize")
+            && method.getParameterTypes().length == 0) {
+            return true;
+        }
         return false;
     }
 
@@ -453,6 +463,9 @@
                 connection + "[" + objectName + "])";
         } else if (methodName.equals("hashCode")) {
             return objectName.hashCode()+connection.hashCode();
+        } else if (methodName.equals("finalize")) {
+            // ignore the finalizer invocation via proxy
+            return null;
         }
 
         throw new RuntimeException("Unexpected method name: " + methodName);
--- a/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java	Wed Jul 15 06:42:49 2015 -0700
@@ -32,7 +32,6 @@
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.Permission;
-import java.security.PermissionCollection;
 import java.security.Permissions;
 import java.security.PrivilegedAction;
 import java.security.PrivilegedActionException;
@@ -46,7 +45,6 @@
 import javax.management.*;
 import javax.management.remote.JMXServerErrorException;
 import javax.management.remote.NotificationResult;
-import javax.management.remote.TargetedNotification;
 import javax.security.auth.Subject;
 import sun.reflect.misc.ReflectUtil;
 
@@ -59,6 +57,7 @@
 import com.sun.jmx.remote.util.ClassLogger;
 import com.sun.jmx.remote.util.EnvHelp;
 import com.sun.jmx.remote.util.OrderClassLoaders;
+import javax.management.loading.ClassLoaderRepository;
 
 /**
  * <p>Implementation of the {@link RMIConnection} interface.  User
@@ -131,20 +130,24 @@
 
         final ClassLoader dcl = defaultClassLoader;
 
-        this.classLoaderWithRepository =
-            AccessController.doPrivileged(
-                new PrivilegedAction<ClassLoaderWithRepository>() {
-                    public ClassLoaderWithRepository run() {
-                        return new ClassLoaderWithRepository(
-                                      mbeanServer.getClassLoaderRepository(),
-                                      dcl);
-                    }
-                },
-
-                withPermissions( new MBeanPermission("*", "getClassLoaderRepository"),
-                                 new RuntimePermission("createClassLoader"))
-            );
-
+        ClassLoaderRepository repository = AccessController.doPrivileged(
+            new PrivilegedAction<ClassLoaderRepository>() {
+                public ClassLoaderRepository run() {
+                    return mbeanServer.getClassLoaderRepository();
+                }
+            },
+            withPermissions(new MBeanPermission("*", "getClassLoaderRepository"))
+        );
+        this.classLoaderWithRepository = AccessController.doPrivileged(
+            new PrivilegedAction<ClassLoaderWithRepository>() {
+                public ClassLoaderWithRepository run() {
+                    return new ClassLoaderWithRepository(
+                        repository,
+                        dcl);
+                }
+            },
+            withPermissions(new RuntimePermission("createClassLoader"))
+        );
 
         this.defaultContextClassLoader =
             AccessController.doPrivileged(
--- a/src/java.rmi/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/java.rmi/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, 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
@@ -102,6 +102,9 @@
      * representation of the proxy.
      * </ul>
      *
+     * <p>If <code>method</code> overrides {@link Object#finalize Object.finalize},
+     * it is ignored.
+     *
      * <p>Otherwise, a remote call is made as follows:
      *
      * <ul>
@@ -144,6 +147,8 @@
     {
         if (method.getDeclaringClass() == Object.class) {
             return invokeObjectMethod(proxy, method, args);
+        } else if ("finalize".equals(method.getName()) && method.getParameterCount() == 0) {
+            return null; // ignore
         } else {
             return invokeRemoteMethod(proxy, method, args);
         }
--- a/src/jdk.crypto.ec/share/native/libsunec/impl/ec.c	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/jdk.crypto.ec/share/native/libsunec/impl/ec.c	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
  * This library is free software; you can redistribute it and/or
@@ -34,6 +34,7 @@
  *   Dr Vipul Gupta <vipul.gupta@sun.com> and
  *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
  *
+ * Last Modified Date from the Original Code: April 2015
  *********************************************************************** */
 
 #include "mplogic.h"
@@ -585,6 +586,10 @@
         return SECFailure;
     }
 
+    if (EC_ValidatePublicKey(ecParams, publicValue, kmflag) != SECSuccess) {
+        return SECFailure;
+    }
+
     memset(derivedSecret, 0, sizeof *derivedSecret);
     len = (ecParams->fieldID.size + 7) >> 3;
     pointQ.len = 2*len + 1;
--- a/src/jdk.crypto.ec/share/native/libsunec/impl/ecc_impl.h	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/jdk.crypto.ec/share/native/libsunec/impl/ecc_impl.h	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
  * This library is free software; you can redistribute it and/or
@@ -34,6 +34,7 @@
  *   Dr Vipul Gupta <vipul.gupta@sun.com> and
  *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
  *
+ * Last Modified Date from the Original Code: November 2013
  *********************************************************************** */
 
 #ifndef _ECC_IMPL_H
--- a/src/jdk.crypto.ec/share/native/libsunec/impl/ecdecode.c	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/jdk.crypto.ec/share/native/libsunec/impl/ecdecode.c	Wed Jul 15 06:42:49 2015 -0700
@@ -34,6 +34,7 @@
  *   Dr Vipul Gupta <vipul.gupta@sun.com> and
  *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
  *
+ * Last Modified Date from the Original Code: March 2012
  *********************************************************************** */
 
 #include <sys/types.h>
--- a/src/jdk.crypto.ec/share/native/libsunec/impl/mpi.c	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/jdk.crypto.ec/share/native/libsunec/impl/mpi.c	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
  * This library is free software; you can redistribute it and/or
@@ -34,6 +34,7 @@
  *   Netscape Communications Corporation
  *   Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
  *
+ * Last Modified Date from the Original Code: June 2014
  *********************************************************************** */
 
 /*  Arbitrary precision integer arithmetic library */
--- a/src/jdk.crypto.ec/share/native/libsunec/impl/oid.c	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/jdk.crypto.ec/share/native/libsunec/impl/oid.c	Wed Jul 15 06:42:49 2015 -0700
@@ -33,6 +33,7 @@
  * Contributor(s):
  *   Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
  *
+ * Last Modified Date from the Original Code: March 2012
  *********************************************************************** */
 
 #include <sys/types.h>
--- a/src/jdk.crypto.ec/share/native/libsunec/impl/secitem.c	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/jdk.crypto.ec/share/native/libsunec/impl/secitem.c	Wed Jul 15 06:42:49 2015 -0700
@@ -32,6 +32,7 @@
  *
  * Contributor(s):
  *
+ * Last Modified Date from the Original Code: March 2012
  *********************************************************************** */
 
 /*
--- a/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Key.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Key.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, 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
@@ -165,7 +165,7 @@
         } else {
             otherEnc = other.getEncoded();
         }
-        return Arrays.equals(thisEnc, otherEnc);
+        return MessageDigest.isEqual(thisEnc, otherEnc);
     }
 
     public int hashCode() {
--- a/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/wrapper/Functions.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/wrapper/Functions.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  */
 
 /* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
@@ -447,22 +447,6 @@
     /**
      * Check the given arrays for equalitiy. This method considers both arrays as
      * equal, if both are <code>null</code> or both have the same length and
-     * contain exactly the same byte values.
-     *
-     * @param array1 The first array.
-     * @param array2 The second array.
-     * @return True, if both arrays are <code>null</code> or both have the same
-     *         length and contain exactly the same byte values. False, otherwise.
-     * @preconditions
-     * @postconditions
-     */
-    public static boolean equals(byte[] array1, byte[] array2) {
-        return Arrays.equals(array1, array2);
-    }
-
-    /**
-     * Check the given arrays for equalitiy. This method considers both arrays as
-     * equal, if both are <code>null</code> or both have the same length and
      * contain exactly the same char values.
      *
      * @param array1 The first array.
@@ -472,7 +456,7 @@
      * @preconditions
      * @postconditions
      */
-    public static boolean equals(char[] array1, char[] array2) {
+    private static boolean equals(char[] array1, char[] array2) {
         return Arrays.equals(array1, array2);
     }
 
--- a/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeGCMCipher.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeGCMCipher.java	Wed Jul 15 06:42:49 2015 -0700
@@ -206,7 +206,7 @@
         }
         if (doEncrypt) {
             requireReinit = Arrays.equals(ivBytes, lastEncIv) &&
-                Arrays.equals(keyBytes, lastEncKey);
+                MessageDigest.isEqual(keyBytes, lastEncKey);
             if (requireReinit) {
                 throw new InvalidAlgorithmParameterException
                     ("Cannot reuse iv for GCM encryption");
--- a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsClient.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsClient.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -184,119 +184,124 @@
         Exception caughtException = null;
         boolean[] doNotRetry = new boolean[servers.length];
 
-        //
-        // The UDP retry strategy is to try the 1st server, and then
-        // each server in order. If no answer, double the timeout
-        // and try each server again.
-        //
-        for (int retry = 0; retry < retries; retry++) {
+        try {
+            //
+            // The UDP retry strategy is to try the 1st server, and then
+            // each server in order. If no answer, double the timeout
+            // and try each server again.
+            //
+            for (int retry = 0; retry < retries; retry++) {
 
-            // Try each name server.
-            for (int i = 0; i < servers.length; i++) {
-                if (doNotRetry[i]) {
-                    continue;
-                }
-
-                // send the request packet and wait for a response.
-                try {
-                    if (debug) {
-                        dprint("SEND ID (" + (retry + 1) + "): " + xid);
+                // Try each name server.
+                for (int i = 0; i < servers.length; i++) {
+                    if (doNotRetry[i]) {
+                        continue;
                     }
 
-                    byte[] msg = null;
-                    msg = doUdpQuery(pkt, servers[i], serverPorts[i],
-                                        retry, xid);
-                    //
-                    // If the matching response is not got within the
-                    // given timeout, check if the response was enqueued
-                    // by some other thread, if not proceed with the next
-                    // server or retry.
-                    //
-                    if (msg == null) {
-                        if (resps.size() > 0) {
-                            msg = lookupResponse(xid);
+                    // send the request packet and wait for a response.
+                    try {
+                        if (debug) {
+                            dprint("SEND ID (" + (retry + 1) + "): " + xid);
                         }
-                        if (msg == null) { // try next server or retry
+
+                        byte[] msg = null;
+                        msg = doUdpQuery(pkt, servers[i], serverPorts[i],
+                                            retry, xid);
+                        //
+                        // If the matching response is not got within the
+                        // given timeout, check if the response was enqueued
+                        // by some other thread, if not proceed with the next
+                        // server or retry.
+                        //
+                        if (msg == null) {
+                            if (resps.size() > 0) {
+                                msg = lookupResponse(xid);
+                            }
+                            if (msg == null) { // try next server or retry
+                                continue;
+                            }
+                        }
+                        Header hdr = new Header(msg, msg.length);
+
+                        if (auth && !hdr.authoritative) {
+                            caughtException = new NameNotFoundException(
+                                    "DNS response not authoritative");
+                            doNotRetry[i] = true;
                             continue;
                         }
-                    }
-                    Header hdr = new Header(msg, msg.length);
+                        if (hdr.truncated) {  // message is truncated -- try TCP
 
-                    if (auth && !hdr.authoritative) {
-                        caughtException = new NameNotFoundException(
-                                "DNS response not authoritative");
-                        doNotRetry[i] = true;
-                        continue;
-                    }
-                    if (hdr.truncated) {    // message is truncated -- try TCP
+                            // Try each server, starting with the one that just
+                            // provided the truncated message.
+                            for (int j = 0; j < servers.length; j++) {
+                                int ij = (i + j) % servers.length;
+                                if (doNotRetry[ij]) {
+                                    continue;
+                                }
+                                try {
+                                    Tcp tcp =
+                                        new Tcp(servers[ij], serverPorts[ij]);
+                                    byte[] msg2;
+                                    try {
+                                        msg2 = doTcpQuery(tcp, pkt);
+                                    } finally {
+                                        tcp.close();
+                                    }
+                                    Header hdr2 = new Header(msg2, msg2.length);
+                                    if (hdr2.query) {
+                                        throw new CommunicationException(
+                                            "DNS error: expecting response");
+                                    }
+                                    checkResponseCode(hdr2);
 
-                        // Try each server, starting with the one that just
-                        // provided the truncated message.
-                        for (int j = 0; j < servers.length; j++) {
-                            int ij = (i + j) % servers.length;
-                            if (doNotRetry[ij]) {
-                                continue;
-                            }
-                            try {
-                                Tcp tcp =
-                                    new Tcp(servers[ij], serverPorts[ij]);
-                                byte[] msg2;
-                                try {
-                                    msg2 = doTcpQuery(tcp, pkt);
-                                } finally {
-                                    tcp.close();
+                                    if (!auth || hdr2.authoritative) {
+                                        // Got a valid response
+                                        hdr = hdr2;
+                                        msg = msg2;
+                                        break;
+                                    } else {
+                                        doNotRetry[ij] = true;
+                                    }
+                                } catch (Exception e) {
+                                    // Try next server, or use UDP response
                                 }
-                                Header hdr2 = new Header(msg2, msg2.length);
-                                if (hdr2.query) {
-                                    throw new CommunicationException(
-                                        "DNS error: expecting response");
-                                }
-                                checkResponseCode(hdr2);
+                            } // servers
+                        }
+                        return new ResourceRecords(msg, msg.length, hdr, false);
 
-                                if (!auth || hdr2.authoritative) {
-                                    // Got a valid response
-                                    hdr = hdr2;
-                                    msg = msg2;
-                                    break;
-                                } else {
-                                    doNotRetry[ij] = true;
-                                }
-                            } catch (Exception e) {
-                                // Try next server, or use UDP response
-                            }
-                        } // servers
-                    }
-                    return new ResourceRecords(msg, msg.length, hdr, false);
-
-                } catch (IOException e) {
-                    if (debug) {
-                        dprint("Caught IOException:" + e);
-                    }
-                    if (caughtException == null) {
-                        caughtException = e;
-                    }
-                    // Use reflection to allow pre-1.4 compilation.
-                    // This won't be needed much longer.
-                    if (e.getClass().getName().equals(
-                            "java.net.PortUnreachableException")) {
+                    } catch (IOException e) {
+                        if (debug) {
+                            dprint("Caught IOException:" + e);
+                        }
+                        if (caughtException == null) {
+                            caughtException = e;
+                        }
+                        // Use reflection to allow pre-1.4 compilation.
+                        // This won't be needed much longer.
+                        if (e.getClass().getName().equals(
+                                "java.net.PortUnreachableException")) {
+                            doNotRetry[i] = true;
+                        }
+                    } catch (NameNotFoundException e) {
+                        // This is authoritative, so return immediately
+                        throw e;
+                    } catch (CommunicationException e) {
+                        if (caughtException == null) {
+                            caughtException = e;
+                        }
+                    } catch (NamingException e) {
+                        if (caughtException == null) {
+                            caughtException = e;
+                        }
                         doNotRetry[i] = true;
                     }
-                } catch (NameNotFoundException e) {
-                    throw e;
-                } catch (CommunicationException e) {
-                    if (caughtException == null) {
-                        caughtException = e;
-                    }
-                } catch (NamingException e) {
-                    if (caughtException == null) {
-                        caughtException = e;
-                    }
-                    doNotRetry[i] = true;
-                }
-            } // servers
-        } // retries
+                } // servers
+            } // retries
 
-        reqs.remove(xid);
+        } finally {
+            reqs.remove(xid); // cleanup
+        }
+
         if (caughtException instanceof NamingException) {
             throw (NamingException) caughtException;
         }
--- a/test/javax/net/ssl/SSLEngine/ConnectionTest.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/test/javax/net/ssl/SSLEngine/ConnectionTest.java	Wed Jul 15 06:42:49 2015 -0700
@@ -81,6 +81,9 @@
         ssle1.setEnabledCipherSuites(new String [] {
             "SSL_RSA_WITH_RC4_128_MD5"});
 
+        ssle2.setEnabledCipherSuites(new String [] {
+            "SSL_RSA_WITH_RC4_128_MD5"});
+
         createBuffers();
     }
 
--- a/test/javax/net/ssl/SSLEngine/LargeBufs.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/test/javax/net/ssl/SSLEngine/LargeBufs.java	Wed Jul 15 06:42:49 2015 -0700
@@ -93,6 +93,7 @@
         createSSLEngines();
 
         System.out.println("Using " + cipher);
+        ssle1.setEnabledCipherSuites(new String [] { cipher });
         ssle2.setEnabledCipherSuites(new String [] { cipher });
 
         createBuffers();
--- a/test/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/test/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java	Wed Jul 15 06:42:49 2015 -0700
@@ -31,7 +31,7 @@
  * @bug 7188657
  * @summary There should be a way to reorder the JSSE ciphers
  * @run main/othervm UseCipherSuitesOrder
- *     TLS_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA
+ *     TLS_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_3DES_EDE_CBC_SHA
  */
 
 import java.io.*;
--- a/test/javax/net/ssl/TLSv11/GenericStreamCipher.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/test/javax/net/ssl/TLSv11/GenericStreamCipher.java	Wed Jul 15 06:42:49 2015 -0700
@@ -93,6 +93,10 @@
         SSLServerSocket sslServerSocket =
             (SSLServerSocket) sslssf.createServerSocket(serverPort);
 
+        // enable a stream cipher
+        sslServerSocket.setEnabledCipherSuites(
+            new String[] {"SSL_RSA_WITH_RC4_128_MD5"});
+
         serverPort = sslServerSocket.getLocalPort();
 
         /*
--- a/test/javax/net/ssl/sanity/ciphersuites/CipherSuitesInOrder.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/test/javax/net/ssl/sanity/ciphersuites/CipherSuitesInOrder.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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,13 +94,6 @@
         "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
         "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
 
-        "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
-        "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
-        "SSL_RSA_WITH_RC4_128_SHA",
-        "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
-        "TLS_ECDH_RSA_WITH_RC4_128_SHA",
-        "SSL_RSA_WITH_RC4_128_MD5",
-
         "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
 
         "TLS_DH_anon_WITH_AES_256_GCM_SHA384",
@@ -114,6 +107,13 @@
         "TLS_DH_anon_WITH_AES_128_CBC_SHA",
         "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
         "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",
+
+        "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
+        "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
+        "SSL_RSA_WITH_RC4_128_SHA",
+        "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
+        "TLS_ECDH_RSA_WITH_RC4_128_SHA",
+        "SSL_RSA_WITH_RC4_128_MD5",
         "TLS_ECDH_anon_WITH_RC4_128_SHA",
         "SSL_DH_anon_WITH_RC4_128_MD5",
 
--- a/test/javax/net/ssl/sanity/interop/ClientJSSEServerJSSE.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/test/javax/net/ssl/sanity/interop/ClientJSSEServerJSSE.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, 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
@@ -33,13 +33,10 @@
 public class ClientJSSEServerJSSE {
 
     public static void main(String[] args) throws Exception {
-        // reset the security property to make sure that the algorithms
+        // reset security properties to make sure that the algorithms
         // and keys used in this test are not disabled.
         Security.setProperty("jdk.tls.disabledAlgorithms", "");
-
-        // MD5 is used in this test case, don't disable MD5 algorithm.
-        Security.setProperty(
-                "jdk.certpath.disabledAlgorithms", "MD2, RSA keySize < 1024");
+        Security.setProperty("jdk.certpath.disabledAlgorithms", "");
 
         CipherTest.main(new JSSEFactory(), args);
     }
--- a/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, 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
@@ -42,6 +42,8 @@
 
 import sun.management.AgentConfigurationError;
 
+import java.security.Security;
+
 /**
  * <p>This class implements unit test for RMI Bootstrap.
  * When called with no arguments main() looks in the directory indicated
@@ -123,6 +125,8 @@
             "com.sun.management.jmxremote.ssl.enabled.protocols";
         public static final String SSL_NEED_CLIENT_AUTH =
             "com.sun.management.jmxremote.ssl.need.client.auth";
+        public static final String SSL_CLIENT_ENABLED_CIPHER_SUITES =
+            "javax.rmi.ssl.client.enabledCipherSuites";
     }
 
     /**
@@ -424,7 +428,7 @@
     }
 
 
-    private void setSslProperties() {
+    private void setSslProperties(String clientEnabledCipherSuites) {
         final String defaultKeyStore =
             getDefaultStoreName(DefaultValues.KEYSTORE);
         final String defaultTrustStore =
@@ -455,6 +459,13 @@
         System.setProperty(PropertyNames.TRUSTSTORE_PASSWD,trustword);
         log.trace("setSslProperties",
                   PropertyNames.TRUSTSTORE_PASSWD+"="+trustword);
+
+        if (clientEnabledCipherSuites != null) {
+            System.setProperty("javax.rmi.ssl.client.enabledCipherSuites",
+                    clientEnabledCipherSuites);
+        } else {
+            System.clearProperty("javax.rmi.ssl.client.enabledCipherSuites");
+        }
     }
 
     private void checkSslConfiguration() {
@@ -507,7 +518,10 @@
                       PropertyNames.SSL_ENABLED_PROTOCOLS + "=" +
                       sslProtocols);
 
-            if (useSsl) setSslProperties();
+            if (useSsl) {
+                setSslProperties(props.getProperty(
+                        PropertyNames.SSL_CLIENT_ENABLED_CIPHER_SUITES));
+            }
         } catch (Exception x) {
             System.out.println("Failed to setup SSL configuration: " + x);
             log.debug("checkSslConfiguration",x);
@@ -839,6 +853,8 @@
      * exit(1) if the test fails.
      **/
     public static void main(String args[]) throws Exception {
+        Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
         try {
             MAX_GET_FREE_PORT_TRIES = Integer.parseInt(System.getProperty("test.getfreeport.max.tries", "10"));
         } catch (NumberFormatException ex) {
--- a/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh	Wed Jul 15 14:44:52 2015 +0200
+++ b/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh	Wed Jul 15 06:42:49 2015 -0700
@@ -29,7 +29,6 @@
 # @library /lib/testlibrary
 # @modules java.management/sun.management
 #          java.management/sun.management.jmxremote
-# @ignore 8077924
 # @build jdk.testlibrary.* TestLogger Utils RmiBootstrapTest
 # @run shell/timeout=300  RmiSslBootstrapTest.sh
 
--- a/test/sun/management/jmxremote/bootstrap/management_ssltest07_ok.properties.in	Wed Jul 15 14:44:52 2015 +0200
+++ b/test/sun/management/jmxremote/bootstrap/management_ssltest07_ok.properties.in	Wed Jul 15 06:42:49 2015 -0700
@@ -2,3 +2,4 @@
 com.sun.management.jmxremote.ssl.enabled.protocols=SSLv2Hello,SSLv3,TLSv1
 com.sun.management.jmxremote.ssl.need.client.auth=true
 com.sun.management.jmxremote.authenticate=false
+javax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_SHA,SSL_RSA_WITH_RC4_128_MD5
--- a/test/sun/management/jmxremote/bootstrap/management_ssltest11_ok.properties.in	Wed Jul 15 14:44:52 2015 +0200
+++ b/test/sun/management/jmxremote/bootstrap/management_ssltest11_ok.properties.in	Wed Jul 15 06:42:49 2015 -0700
@@ -3,3 +3,4 @@
 com.sun.management.jmxremote.ssl.need.client.auth=true
 com.sun.management.jmxremote.ssl.config.file=@TEST-SRC@/jmxremote_ssltest11_ok.ssl
 com.sun.management.jmxremote.authenticate=false
+javax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_SHA,SSL_RSA_WITH_RC4_128_MD5
--- a/test/sun/security/ec/TestEC.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/test/sun/security/ec/TestEC.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, 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
@@ -60,13 +60,10 @@
 public class TestEC {
 
     public static void main(String[] args) throws Exception {
-        // reset the security property to make sure that the algorithms
+        // reset security properties to make sure that the algorithms
         // and keys used in this test are not disabled.
         Security.setProperty("jdk.tls.disabledAlgorithms", "");
-
-        // MD5 is used in this test case, don't disable MD5 algorithm.
-        Security.setProperty(
-                "jdk.certpath.disabledAlgorithms", "MD2, RSA keySize < 1024");
+        Security.setProperty("jdk.certpath.disabledAlgorithms", "");
 
         ProvidersSnapshot snapshot = ProvidersSnapshot.create();
         try {
--- a/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, 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
@@ -43,18 +43,15 @@
     private static String[] cmdArgs;
 
     public static void main(String[] args) throws Exception {
-        // reset the security property to make sure that the algorithms
-        // and keys used in this test are not disabled.
-        Security.setProperty("jdk.tls.disabledAlgorithms", "");
-
         cmdArgs = args;
         main(new ClientJSSEServerJSSE());
     }
 
     public void main(Provider p) throws Exception {
-        // MD5 is used in this test case, don't disable MD5 algorithm.
-        Security.setProperty(
-                "jdk.certpath.disabledAlgorithms", "MD2, RSA keySize < 1024");
+        // reset security properties to make sure that the algorithms
+        // and keys used in this test are not disabled.
+        Security.setProperty("jdk.tls.disabledAlgorithms", "");
+        Security.setProperty("jdk.certpath.disabledAlgorithms", "");
 
         if (p.getService("KeyFactory", "EC") == null) {
             System.out.println("Provider does not support EC, skipping");
--- a/test/sun/security/ssl/DHKeyExchange/DHEKeySizing.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/test/sun/security/ssl/DHKeyExchange/DHEKeySizing.java	Wed Jul 15 06:42:49 2015 -0700
@@ -377,9 +377,10 @@
     }
 
     public static void main(String args[]) throws Exception {
-        // reset the security property to make sure that the algorithms
+        // reset security properties to make sure that the algorithms
         // and keys used in this test are not disabled.
         Security.setProperty("jdk.tls.disabledAlgorithms", "");
+        Security.setProperty("jdk.certpath.disabledAlgorithms", "");
 
         if (args.length != 4) {
             System.out.println(
--- a/test/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java	Wed Jul 15 14:44:52 2015 +0200
+++ b/test/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java	Wed Jul 15 06:42:49 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -21,19 +21,22 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4392475
  * @summary Calling setWantClientAuth(true) disables anonymous suites
  * @run main/othervm/timeout=180 AnonCipherWithWantClientAuth
- *
- *     SunJSSE does not support dynamic system properties, no way to re-use
- *     system properties in samevm/agentvm mode.
  */
 
 import java.io.*;
 import java.net.*;
 import javax.net.ssl.*;
+import java.security.Security;
 
 public class AnonCipherWithWantClientAuth {
 
@@ -156,6 +159,11 @@
     volatile Exception clientException = null;
 
     public static void main(String[] args) throws Exception {
+        // reset security properties to make sure that the algorithms
+        // and keys used in this test are not disabled.
+        Security.setProperty("jdk.tls.disabledAlgorithms", "");
+        Security.setProperty("jdk.certpath.disabledAlgorithms", "");
+
         String keyFilename =
             System.getProperty("test.src", "./") + "/" + pathToStores +
                 "/" + keyStoreFile;