--- old/src/java.base/share/classes/java/security/MessageDigest.java Fri Sep 30 01:32:57 2016 +++ new/src/java.base/share/classes/java/security/MessageDigest.java Fri Sep 30 01:32:56 2016 @@ -32,11 +32,14 @@ import java.io.PrintStream; import java.io.InputStream; import java.io.ByteArrayInputStream; - +import java.security.InvalidKeyException; import java.nio.ByteBuffer; import sun.security.util.Debug; +import sun.security.util.MessageDigestSpi2; +import javax.crypto.SecretKey; + /** * This MessageDigest class provides applications the functionality of a * message digest algorithm, such as SHA-1 or SHA-256. @@ -548,7 +551,7 @@ * and its original parent (Object). */ - static class Delegate extends MessageDigest { + static class Delegate extends MessageDigest implements MessageDigestSpi2 { // The provider implementation (delegate) private MessageDigestSpi digestSpi; @@ -601,6 +604,14 @@ digestSpi.engineUpdate(input); } + public void engineUpdate(SecretKey key) throws InvalidKeyException { + if (digestSpi instanceof MessageDigestSpi2) { + ((MessageDigestSpi2)digestSpi).engineUpdate(key); + } else { + throw new UnsupportedOperationException + ("Digest does not support update of SecretKey object"); + } + } protected byte[] engineDigest() { return digestSpi.engineDigest(); } --- old/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java Fri Sep 30 01:32:58 2016 +++ new/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java Fri Sep 30 01:32:58 2016 @@ -49,6 +49,7 @@ import sun.security.ssl.CipherSuite.*; import static sun.security.ssl.CipherSuite.PRF.*; import sun.security.util.KeyUtil; +import sun.security.util.MessageDigestSpi2; import sun.security.provider.certpath.OCSPResponse; /** @@ -2124,63 +2125,14 @@ md.update(temp); } - private static final Class delegate; - private static final Field spiField; - - static { - try { - delegate = Class.forName("java.security.MessageDigest$Delegate"); - spiField = delegate.getDeclaredField("digestSpi"); - } catch (Exception e) { - throw new RuntimeException("Reflection failed", e); - } - makeAccessible(spiField); - } - - private static void makeAccessible(final AccessibleObject o) { - AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Object run() { - o.setAccessible(true); - return null; - } - }); - } - - // ConcurrentHashMap does not allow null values, use this marker object - private static final Object NULL_OBJECT = new Object(); - - // cache Method objects per Spi class - // Note that this will prevent the Spi classes from being GC'd. We assume - // that is not a problem. - private static final Map,Object> methodCache = - new ConcurrentHashMap<>(); - private static void digestKey(MessageDigest md, SecretKey key) { try { - // Verify that md is implemented via MessageDigestSpi, not - // via JDK 1.1 style MessageDigest subclassing. - if (md.getClass() != delegate) { - throw new Exception("Digest is not a MessageDigestSpi"); - } - MessageDigestSpi spi = (MessageDigestSpi)spiField.get(md); - Class clazz = spi.getClass(); - Object r = methodCache.get(clazz); - if (r == null) { - try { - r = clazz.getDeclaredMethod("implUpdate", SecretKey.class); - makeAccessible((Method)r); - } catch (NoSuchMethodException e) { - r = NULL_OBJECT; - } - methodCache.put(clazz, r); - } - if (r == NULL_OBJECT) { + if (md instanceof MessageDigestSpi2) { + ((MessageDigestSpi2)md).engineUpdate(key); + } else { throw new Exception( "Digest does not support implUpdate(SecretKey)"); } - Method update = (Method)r; - update.invoke(spi, key); } catch (Exception e) { throw new RuntimeException( "Could not obtain encoded key and " --- old/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Digest.java Fri Sep 30 01:32:59 2016 +++ new/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Digest.java Fri Sep 30 01:32:59 2016 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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,8 @@ import sun.nio.ch.DirectBuffer; +import sun.security.util.MessageDigestSpi2; + import sun.security.pkcs11.wrapper.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*; @@ -49,7 +51,8 @@ * @author Andreas Sterbenz * @since 1.5 */ -final class P11Digest extends MessageDigestSpi implements Cloneable { +final class P11Digest extends MessageDigestSpi implements Cloneable, + MessageDigestSpi2 { /* fields initialized, no session acquired */ private final static int S_BLANK = 1; @@ -233,10 +236,11 @@ } // Called by SunJSSE via reflection during the SSL 3.0 handshake if - // the master secret is sensitive. We may want to consider making this - // method public in a future release. - protected void implUpdate(SecretKey key) throws InvalidKeyException { - + // the master secret is sensitive. + // Note: Change to protected after this method is moved from + // sun.security.util.MessageSpi2 interface to + // java.security.MessageDigestSpi class + public void engineUpdate(SecretKey key) throws InvalidKeyException { // SunJSSE calls this method only if the key does not have a RAW // encoding, i.e. if it is sensitive. Therefore, no point in calling // SecretKeyFactory to try to convert it. Just verify it ourselves. --- /dev/null Fri Sep 30 01:33:01 2016 +++ new/src/java.base/share/classes/sun/security/util/MessageDigestSpi2.java Fri Sep 30 01:33:01 2016 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, 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.InvalidKeyException; +import javax.crypto.SecretKey; + +/** + * Interface for new MessageDigestSpi method(s) which should be considered + * for future releases + */ +public interface MessageDigestSpi2 { + + /** + * Updates the digest using the specified key. + * + * @param key the key whose value is to be digested. + */ + void engineUpdate(SecretKey key) throws InvalidKeyException; +}