diff --git a/.hgtags b/.hgtags index 4395047b93d8cc187c2add3e121b410c8d535de6..5fccf6901f887db4d0afd7e2cf7b91f95d9dd808 100644 --- a/.hgtags +++ b/.hgtags @@ -312,6 +312,28 @@ be30cb2a3088f2b7b334b499f7eddbd5312312a7 jdk8u20-b23 dfb9f24d56b51e5a2ca26e77fc69a2464d51a4d3 jdk8u20-b24 dfb9f24d56b51e5a2ca26e77fc69a2464d51a4d3 jdk8u20-b25 dd229c5f57bff4e75a70908294a13072b9a48385 jdk8u20-b26 +abca9f6f1a10e9f91b2538bbe7870f54f550d986 jdk8u25-b00 +7d0627679c9fdeaaaa9fe15c7cc11af0763621ec jdk8u25-b01 +b0277ec994b751ebb761814675352506cd56bcd6 jdk8u25-b02 +5606d84f30bab5ed4bc5776572edd469fb013e13 jdk8u25-b03 +40630cd55da8a2db7980249dc31af285965cb5e9 jdk8u25-b04 +75b48287a1b3fc5757ac473f72c8918c7f345ffc jdk8u25-b05 +5b80b4b22b4ca0b630c7f1cec3605da7694168e2 jdk8u25-b06 +0e0a35b0bf0ff5852026c50038d5c2ecb26c075c jdk8u25-b07 +d7d221f56fd17b96bab4440448641a844f9e92cd jdk8u25-b08 +0c6cf43c5bcf0917d07a1bc94adb7a091f18f32c jdk8u25-b09 +1317d94e95861a47fee8258903b652af70a3493c jdk8u25-b10 +2104dfd9a4c2b519cdca019aec938db539bf4f3f jdk8u25-b11 +eaaa9a04b9fdcfa4a830b811ed209eb2c45a4a6b jdk8u25-b12 +c3a855402b923d3ba819b05292a971953fc8ed0b jdk8u25-b13 +2a6df63ca0f0f59bb730638b05c72d77a23f93c8 jdk8u25-b14 +412d9ade90401d098f3662bd688ab393008423bd jdk8u25-b15 +f07bc5dab84c67f5d1dccbab318ee1c5485c852d jdk8u25-b16 +0000000000000000000000000000000000000000 jdk8u25-b16 +0000000000000000000000000000000000000000 jdk8u25-b16 +d067890f970f3a712f870f6311d20f3359b6eaf0 jdk8u25-b16 +67b22a82345bfa1ae1492679bdf3c4d54f4eacde jdk8u25-b17 +a4e88eaf15ea0569f3275a807a976fe0e04a086c jdk8u25-b18 e6ed015afbbf3459ba3297e270b4f3170e989c80 jdk8u40-b00 6e223d48080ef40f4ec11ecbcd19b4a20813b9eb jdk8u40-b01 4797cd0713b44b009525f1276d571ade7e24f3f5 jdk8u40-b02 @@ -322,3 +344,4 @@ d587834579dadd18cb8b096e61d92e2dbccc2782 jdk8u40-b05 07f0e22b5c238dd7b89fedbed35f02ac6b392c96 jdk8u40-b07 0f0d70abca09b4ddb0981204ad5a427d4ce935e9 jdk8u40-b08 064adeb65ce82f9ff3cc7898e59d19eb64743c63 jdk8u40-b09 +c3a4729c70fa29d79ad77e0643ad7715ebbc96b5 jdk8u40-b10 diff --git a/make/lib/CoreLibraries.gmk b/make/lib/CoreLibraries.gmk index 0a2773430692f1737f5344c6ec3625380ab02c89..a36bf90b93ed1db71c82c5506c21112b656e37cd 100644 --- a/make/lib/CoreLibraries.gmk +++ b/make/lib/CoreLibraries.gmk @@ -264,7 +264,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBZIP, \ $(call SET_SHARED_LIBRARY_ORIGIN) \ $(EXPORT_ZIP_FUNCS), \ LDFLAGS_windows := -export:ZIP_Open -export:ZIP_Close -export:ZIP_FindEntry \ - -export:ZIP_ReadEntry -export:ZIP_GetNextEntry jvm.lib \ + -export:ZIP_ReadEntry -export:ZIP_GetNextEntry -export:ZIP_CRC32 jvm.lib \ $(WIN_JAVA_LIB), \ LDFLAGS_SUFFIX_linux := -ljvm -ljava $(LIBZ), \ LDFLAGS_SUFFIX_solaris := -ljvm -ljava $(LIBZ) -lc, \ diff --git a/make/mapfiles/libnet/mapfile-vers b/make/mapfiles/libnet/mapfile-vers index 1b6a14864dc4a63191f334295b7ea6081d6fa56c..9e07f44b14aaeaf98f1273fde0deb6c9b892a233 100644 --- a/make/mapfiles/libnet/mapfile-vers +++ b/make/mapfiles/libnet/mapfile-vers @@ -28,6 +28,8 @@ SUNWprivate_1.1 { global: JNI_OnLoad; + Java_java_net_AbstractPlainDatagramSocketImpl_init; + Java_java_net_AbstractPlainDatagramSocketImpl_dataAvailable; Java_java_net_PlainSocketImpl_socketListen; Java_java_net_PlainDatagramSocketImpl_getTTL; Java_java_net_PlainDatagramSocketImpl_init; diff --git a/src/share/classes/com/sun/org/apache/xml/internal/security/Init.java b/src/share/classes/com/sun/org/apache/xml/internal/security/Init.java index 6176370878a8ad2e45a99dc074aef4e33585a892..5f3b9f53c8f8f5501acbec9e6650ef328296d3fc 100644 --- a/src/share/classes/com/sun/org/apache/xml/internal/security/Init.java +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/Init.java @@ -25,6 +25,8 @@ package com.sun.org.apache.xml.internal.security; import java.io.InputStream; import java.security.AccessController; import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.List; @@ -35,6 +37,7 @@ import javax.xml.parsers.DocumentBuilderFactory; import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper; import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithm; import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer; +import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolver; import com.sun.org.apache.xml.internal.security.transforms.Transform; import com.sun.org.apache.xml.internal.security.utils.ElementProxy; @@ -118,43 +121,50 @@ public class Init { log.log(java.util.logging.Level.FINE, "Registering default algorithms"); } try { - // - // Bind the default prefixes - // - ElementProxy.registerDefaultPrefixes(); - - // - // Set the default Transforms - // - Transform.registerDefaultAlgorithms(); - - // - // Set the default signature algorithms - // - SignatureAlgorithm.registerDefaultAlgorithms(); - - // - // Set the default JCE algorithms - // - JCEMapper.registerDefaultAlgorithms(); - - // - // Set the default c14n algorithms - // - Canonicalizer.registerDefaultAlgorithms(); - - // - // Register the default resolvers - // - ResourceResolver.registerDefaultResolvers(); - - // - // Register the default key resolvers - // - KeyResolver.registerDefaultResolvers(); - } catch (Exception ex) { - log.log(java.util.logging.Level.SEVERE, ex.getMessage(), ex); - ex.printStackTrace(); + AccessController.doPrivileged(new PrivilegedExceptionAction(){ + @Override public Void run() throws XMLSecurityException { + // + // Bind the default prefixes + // + ElementProxy.registerDefaultPrefixes(); + + // + // Set the default Transforms + // + Transform.registerDefaultAlgorithms(); + + // + // Set the default signature algorithms + // + SignatureAlgorithm.registerDefaultAlgorithms(); + + // + // Set the default JCE algorithms + // + JCEMapper.registerDefaultAlgorithms(); + + // + // Set the default c14n algorithms + // + Canonicalizer.registerDefaultAlgorithms(); + + // + // Register the default resolvers + // + ResourceResolver.registerDefaultResolvers(); + + // + // Register the default key resolvers + // + KeyResolver.registerDefaultResolvers(); + + return null; + } + }); + } catch (PrivilegedActionException ex) { + XMLSecurityException xse = (XMLSecurityException)ex.getException(); + log.log(java.util.logging.Level.SEVERE, xse.getMessage(), xse); + xse.printStackTrace(); } } diff --git a/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java b/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java index ca7d42a869ae144674616f6b2fb87b1119eca8e1..9fc352579595b4b0a4b2f67da41ca1215402e32e 100644 --- a/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java @@ -27,6 +27,7 @@ import java.util.concurrent.ConcurrentHashMap; import com.sun.org.apache.xml.internal.security.encryption.XMLCipher; import com.sun.org.apache.xml.internal.security.signature.XMLSignature; +import com.sun.org.apache.xml.internal.security.utils.JavaUtils; import org.w3c.dom.Element; @@ -49,8 +50,11 @@ public class JCEMapper { * * @param id * @param algorithm + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the JCE algorithm */ public static void register(String id, Algorithm algorithm) { + JavaUtils.checkRegisterPermission(); algorithmsMap.put(id, algorithm); } @@ -292,8 +296,11 @@ public class JCEMapper { /** * Sets the default Provider for obtaining the security algorithms * @param provider the default providerId. + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to set the JCE provider */ public static void setProviderId(String provider) { + JavaUtils.checkRegisterPermission(); providerName = provider; } diff --git a/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java b/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java index 4748a6bc882ba84e0b4ab279fbb43a59f1095d93..ada9ea53d77ba04d452c99369d157d0afa97c8c4 100644 --- a/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java @@ -37,6 +37,7 @@ import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; import com.sun.org.apache.xml.internal.security.signature.XMLSignature; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException; import com.sun.org.apache.xml.internal.security.utils.Constants; +import com.sun.org.apache.xml.internal.security.utils.JavaUtils; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -314,18 +315,21 @@ public class SignatureAlgorithm extends Algorithm { } /** - * Registers implementing class of the Transform algorithm with algorithmURI + * Registers implementing class of the SignatureAlgorithm with algorithmURI * - * @param algorithmURI algorithmURI URI representation of Transform algorithm. + * @param algorithmURI algorithmURI URI representation of SignatureAlgorithm. * @param implementingClass implementingClass the implementing class of * {@link SignatureAlgorithmSpi} * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI is already registered * @throws XMLSignatureException + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the signature algorithm */ @SuppressWarnings("unchecked") public static void register(String algorithmURI, String implementingClass) throws AlgorithmAlreadyRegisteredException, ClassNotFoundException, XMLSignatureException { + JavaUtils.checkRegisterPermission(); if (log.isLoggable(java.util.logging.Level.FINE)) { log.log(java.util.logging.Level.FINE, "Try to register " + algorithmURI + " " + implementingClass); } @@ -352,15 +356,18 @@ public class SignatureAlgorithm extends Algorithm { /** * Registers implementing class of the Transform algorithm with algorithmURI * - * @param algorithmURI algorithmURI URI representation of Transform algorithm. + * @param algorithmURI algorithmURI URI representation of SignatureAlgorithm. * @param implementingClass implementingClass the implementing class of * {@link SignatureAlgorithmSpi} * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI is already registered * @throws XMLSignatureException + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the signature algorithm */ public static void register(String algorithmURI, Class implementingClass) throws AlgorithmAlreadyRegisteredException, ClassNotFoundException, XMLSignatureException { + JavaUtils.checkRegisterPermission(); if (log.isLoggable(java.util.logging.Level.FINE)) { log.log(java.util.logging.Level.FINE, "Try to register " + algorithmURI + " " + implementingClass); } diff --git a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java index 2f0b31f5ed4dfe301cedb328acdbcd0e21f3f65f..ae33b72c91d69e79920795dc7cba20375b20871c 100644 --- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java @@ -41,6 +41,7 @@ import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicaliz import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315WithComments; import com.sun.org.apache.xml.internal.security.c14n.implementations.CanonicalizerPhysical; import com.sun.org.apache.xml.internal.security.exceptions.AlgorithmAlreadyRegisteredException; +import com.sun.org.apache.xml.internal.security.utils.JavaUtils; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -142,10 +143,13 @@ public class Canonicalizer { * @param algorithmURI * @param implementingClass * @throws AlgorithmAlreadyRegisteredException + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the canonicalizer */ @SuppressWarnings("unchecked") public static void register(String algorithmURI, String implementingClass) throws AlgorithmAlreadyRegisteredException, ClassNotFoundException { + JavaUtils.checkRegisterPermission(); // check whether URI is already registered Class registeredClass = canonicalizerHash.get(algorithmURI); @@ -166,9 +170,12 @@ public class Canonicalizer { * @param algorithmURI * @param implementingClass * @throws AlgorithmAlreadyRegisteredException + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the canonicalizer */ - public static void register(String algorithmURI, Class implementingClass) + public static void register(String algorithmURI, Class implementingClass) throws AlgorithmAlreadyRegisteredException, ClassNotFoundException { + JavaUtils.checkRegisterPermission(); // check whether URI is already registered Class registeredClass = canonicalizerHash.get(algorithmURI); diff --git a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java index fe541ff044f6111eb119905fc57a428bcf41f945..e8622d938b67810d942a9e25baa252f25fa0f90a 100644 --- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java @@ -42,6 +42,7 @@ import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509SKIResolver; import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509SubjectNameResolver; import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver; +import com.sun.org.apache.xml.internal.security.utils.JavaUtils; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -175,9 +176,12 @@ public class KeyResolver { * @throws InstantiationException * @throws IllegalAccessException * @throws ClassNotFoundException + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the key resolver */ public static void register(String className, boolean globalResolver) throws ClassNotFoundException, IllegalAccessException, InstantiationException { + JavaUtils.checkRegisterPermission(); KeyResolverSpi keyResolverSpi = (KeyResolverSpi) Class.forName(className).newInstance(); keyResolverSpi.setGlobalResolver(globalResolver); @@ -195,8 +199,11 @@ public class KeyResolver { * * @param className * @param globalResolver Whether the KeyResolverSpi is a global resolver or not + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the key resolver */ public static void registerAtStart(String className, boolean globalResolver) { + JavaUtils.checkRegisterPermission(); KeyResolverSpi keyResolverSpi = null; Exception ex = null; try { @@ -228,11 +235,14 @@ public class KeyResolver { * * @param keyResolverSpi a KeyResolverSpi instance to register * @param start whether to register the KeyResolverSpi at the start of the list or not + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the key resolver */ public static void register( KeyResolverSpi keyResolverSpi, boolean start ) { + JavaUtils.checkRegisterPermission(); KeyResolver resolver = new KeyResolver(keyResolverSpi); if (start) { resolverVector.add(0, resolver); @@ -254,9 +264,12 @@ public class KeyResolver { * @throws InstantiationException * @throws IllegalAccessException * @throws ClassNotFoundException + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the key resolver */ public static void registerClassNames(List classNames) throws ClassNotFoundException, IllegalAccessException, InstantiationException { + JavaUtils.checkRegisterPermission(); List keyResolverList = new ArrayList(classNames.size()); for (String className : classNames) { KeyResolverSpi keyResolverSpi = diff --git a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java index 37d67ba9f24307506f2e173b9451eeb25d3358f4..3fc1d21bb9cebd63eac06751c7686d288125e5b3 100644 --- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java @@ -46,6 +46,7 @@ import com.sun.org.apache.xml.internal.security.transforms.implementations.Trans import com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT; import com.sun.org.apache.xml.internal.security.utils.Constants; import com.sun.org.apache.xml.internal.security.utils.HelperNodeList; +import com.sun.org.apache.xml.internal.security.utils.JavaUtils; import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy; import com.sun.org.apache.xml.internal.security.utils.XMLUtils; import org.w3c.dom.Document; @@ -181,11 +182,14 @@ public final class Transform extends SignatureElementProxy { * class of {@link TransformSpi} * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI * is already registered + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the transform */ @SuppressWarnings("unchecked") public static void register(String algorithmURI, String implementingClass) throws AlgorithmAlreadyRegisteredException, ClassNotFoundException, InvalidTransformException { + JavaUtils.checkRegisterPermission(); // are we already registered? Class transformSpi = transformSpiHash.get(algorithmURI); if (transformSpi != null) { @@ -206,9 +210,12 @@ public final class Transform extends SignatureElementProxy { * class of {@link TransformSpi} * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI * is already registered + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register the transform */ public static void register(String algorithmURI, Class implementingClass) throws AlgorithmAlreadyRegisteredException { + JavaUtils.checkRegisterPermission(); // are we already registered? Class transformSpi = transformSpiHash.get(algorithmURI); if (transformSpi != null) { diff --git a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java index ac7a53eba4fed1b8c4daadfe6abb9f901d6dc4ff..fe8bdb1f1d67d2b3c2c9312f5f242e48494f0b72 100644 --- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java @@ -468,9 +468,12 @@ public abstract class ElementProxy { * @param namespace * @param prefix * @throws XMLSecurityException + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to set the default prefix */ public static void setDefaultPrefix(String namespace, String prefix) throws XMLSecurityException { + JavaUtils.checkRegisterPermission(); if (prefixMappings.containsValue(prefix)) { String storedPrefix = prefixMappings.get(namespace); if (!storedPrefix.equals(prefix)) { diff --git a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java index cf55f4088ba1d556ebefd1666e9a99f5c63058a8..ee3dfbe63534d60c37d1a115d6e8b655f8304a7f 100644 --- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java @@ -28,6 +28,7 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.security.SecurityPermission; /** * A collection of different, general-purpose methods for JAVA-specific things @@ -39,6 +40,10 @@ public class JavaUtils { private static java.util.logging.Logger log = java.util.logging.Logger.getLogger(JavaUtils.class.getName()); + private static final SecurityPermission REGISTER_PERMISSION = + new SecurityPermission( + "com.sun.org.apache.xml.internal.security.register"); + private JavaUtils() { // we don't allow instantiation } @@ -145,4 +150,21 @@ public class JavaUtils { return retBytes; } + + /** + * Throws a {@code SecurityException} if a security manager is installed + * and the caller is not allowed to register an implementation of an + * algorithm, transform, or other security sensitive XML Signature function. + * + * @throws SecurityException if a security manager is installed and the + * caller has not been granted the + * {@literal "com.sun.org.apache.xml.internal.security.register"} + * {@code SecurityPermission} + */ + public static void checkRegisterPermission() { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(REGISTER_PERMISSION); + } + } } diff --git a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java index 620b6735b8f391557774c497576aac9dbbb1fd11..585f7f62495175e4607429ed93194478b9e63672 100644 --- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java @@ -80,32 +80,44 @@ public class XMLUtils { /** * Set the prefix for the digital signature namespace * @param prefix the new prefix for the digital signature namespace + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to set the prefix */ public static void setDsPrefix(String prefix) { + JavaUtils.checkRegisterPermission(); dsPrefix = prefix; } /** * Set the prefix for the digital signature 1.1 namespace * @param prefix the new prefix for the digital signature 1.1 namespace + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to set the prefix */ public static void setDs11Prefix(String prefix) { + JavaUtils.checkRegisterPermission(); ds11Prefix = prefix; } /** * Set the prefix for the encryption namespace * @param prefix the new prefix for the encryption namespace + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to set the prefix */ public static void setXencPrefix(String prefix) { + JavaUtils.checkRegisterPermission(); xencPrefix = prefix; } /** * Set the prefix for the encryption namespace 1.1 * @param prefix the new prefix for the encryption namespace 1.1 + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to set the prefix */ public static void setXenc11Prefix(String prefix) { + JavaUtils.checkRegisterPermission(); xenc11Prefix = prefix; } diff --git a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java index 7570a01906481adb64737f8915e5428bbe221e1a..012d2fb8bc46fa9ad49f61454695ede2593b4394 100644 --- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.Map; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; +import com.sun.org.apache.xml.internal.security.utils.JavaUtils; import com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverDirectHTTP; import com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverFragment; import com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverLocalFilesystem; @@ -199,9 +200,12 @@ public class ResourceResolver { * the class cannot be registered. * * @param className the name of the ResourceResolverSpi class to be registered + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register a resource resolver */ @SuppressWarnings("unchecked") public static void register(String className) { + JavaUtils.checkRegisterPermission(); try { Class resourceResolverClass = (Class) Class.forName(className); @@ -216,9 +220,12 @@ public class ResourceResolver { * list. This method logs a warning if the class cannot be registered. * * @param className the name of the ResourceResolverSpi class to be registered + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register a resource resolver */ @SuppressWarnings("unchecked") public static void registerAtStart(String className) { + JavaUtils.checkRegisterPermission(); try { Class resourceResolverClass = (Class) Class.forName(className); @@ -233,8 +240,11 @@ public class ResourceResolver { * cannot be registered. * @param className * @param start + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register a resource resolver */ public static void register(Class className, boolean start) { + JavaUtils.checkRegisterPermission(); try { ResourceResolverSpi resourceResolverSpi = className.newInstance(); register(resourceResolverSpi, start); @@ -250,8 +260,11 @@ public class ResourceResolver { * cannot be registered. * @param resourceResolverSpi * @param start + * @throws SecurityException if a security manager is installed and the + * caller does not have permission to register a resource resolver */ public static void register(ResourceResolverSpi resourceResolverSpi, boolean start) { + JavaUtils.checkRegisterPermission(); synchronized(resolverList) { if (start) { resolverList.add(0, new ResourceResolver(resourceResolverSpi)); diff --git a/src/share/classes/java/lang/Class.java b/src/share/classes/java/lang/Class.java index 2440baaaba545a6775c64f0a65635389641bb0eb..43c8c0e8ec73bab1159ea0e49b8cf4ab6cca0a8c 100644 --- a/src/share/classes/java/lang/Class.java +++ b/src/share/classes/java/lang/Class.java @@ -260,8 +260,8 @@ public final class Class implements java.io.Serializable, @CallerSensitive public static Class forName(String className) throws ClassNotFoundException { - return forName0(className, true, - ClassLoader.getClassLoader(Reflection.getCallerClass())); + Class caller = Reflection.getCallerClass(); + return forName0(className, true, ClassLoader.getClassLoader(caller), caller); } @@ -331,22 +331,27 @@ public final class Class implements java.io.Serializable, ClassLoader loader) throws ClassNotFoundException { - if (sun.misc.VM.isSystemDomainLoader(loader)) { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - ClassLoader ccl = ClassLoader.getClassLoader(Reflection.getCallerClass()); + Class caller = null; + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + // Reflective call to get caller class is only needed if a security manager + // is present. Avoid the overhead of making this call otherwise. + caller = Reflection.getCallerClass(); + if (sun.misc.VM.isSystemDomainLoader(loader)) { + ClassLoader ccl = ClassLoader.getClassLoader(caller); if (!sun.misc.VM.isSystemDomainLoader(ccl)) { sm.checkPermission( SecurityConstants.GET_CLASSLOADER_PERMISSION); } } } - return forName0(name, initialize, loader); + return forName0(name, initialize, loader, caller); } - /** Called after security checks have been made. */ + /** Called after security check for system loader access checks have been made. */ private static native Class forName0(String name, boolean initialize, - ClassLoader loader) + ClassLoader loader, + Class caller) throws ClassNotFoundException; /** diff --git a/src/share/classes/java/lang/invoke/MethodType.java b/src/share/classes/java/lang/invoke/MethodType.java index e96b70e233ad0fb29ef37da0ed601ae2f5728544..96d692f7dda39d0daa773125028dcb387ebb44f7 100644 --- a/src/share/classes/java/lang/invoke/MethodType.java +++ b/src/share/classes/java/lang/invoke/MethodType.java @@ -726,7 +726,7 @@ class MethodType implements java.io.Serializable { * @return the parameter types (as an immutable list) */ public List> parameterList() { - return Collections.unmodifiableList(Arrays.asList(ptypes)); + return Collections.unmodifiableList(Arrays.asList(ptypes.clone())); } /*non-public*/ Class lastParameterType() { diff --git a/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java b/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java index 555ca8456c825265f743c424b6636c12cb1635fc..1793cfca130618f800bd3e2b12bbfe0024c0c5b4 100644 --- a/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java +++ b/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java @@ -68,6 +68,7 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl return null; } }); + init(); } /** @@ -362,4 +363,7 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl protected boolean nativeConnectDisabled() { return connectDisabled; } + + native int dataAvailable(); + private static native void init(); } diff --git a/src/share/classes/java/net/DatagramSocket.java b/src/share/classes/java/net/DatagramSocket.java index 54799a88823a906be2fef5fa5f02d4f106322bd5..2fdabb597160ba5803321a95f4f2fdca21fa0664 100644 --- a/src/share/classes/java/net/DatagramSocket.java +++ b/src/share/classes/java/net/DatagramSocket.java @@ -83,6 +83,17 @@ class DatagramSocket implements java.io.Closeable { */ boolean oldImpl = false; + /** + * Set when a socket is ST_CONNECTED until we are certain + * that any packets which might have been received prior + * to calling connect() but not read by the application + * have been read. During this time we check the source + * address of all packets received to be sure they are from + * the connected destination. Other packets are read but + * silently dropped. + */ + private boolean explicitFilter = false; + private int bytesLeftToFilter; /* * Connection state: * ST_NOT_CONNECTED = socket not connected @@ -142,6 +153,15 @@ class DatagramSocket implements java.io.Closeable { // socket is now connected by the impl connectState = ST_CONNECTED; + // Do we need to filter some packets? + int avail = getImpl().dataAvailable(); + if (avail == -1) { + throw new SocketException(); + } + explicitFilter = avail > 0; + if (explicitFilter) { + bytesLeftToFilter = getReceiveBufferSize(); + } } catch (SocketException se) { // connection will be emulated by DatagramSocket @@ -490,6 +510,7 @@ class DatagramSocket implements java.io.Closeable { connectedAddress = null; connectedPort = -1; connectState = ST_NOT_CONNECTED; + explicitFilter = false; } } @@ -748,10 +769,13 @@ class DatagramSocket implements java.io.Closeable { } // end of while } } - if (connectState == ST_CONNECTED_NO_IMPL) { + DatagramPacket tmp = null; + if ((connectState == ST_CONNECTED_NO_IMPL) || explicitFilter) { // We have to do the filtering the old fashioned way since // the native impl doesn't support connect or the connect - // via the impl failed. + // via the impl failed, or .. "explicitFilter" may be set when + // a socket is connected via the impl, for a period of time + // when packets from other sources might be queued on socket. boolean stop = false; while (!stop) { InetAddress peekAddress = null; @@ -770,8 +794,14 @@ class DatagramSocket implements java.io.Closeable { if ((!connectedAddress.equals(peekAddress)) || (connectedPort != peekPort)) { // throw the packet away and silently continue - DatagramPacket tmp = new DatagramPacket(new byte[1], 1); + tmp = new DatagramPacket( + new byte[1024], 1024); getImpl().receive(tmp); + if (explicitFilter) { + if (checkFiltering(tmp)) { + stop = true; + } + } } else { stop = true; } @@ -780,7 +810,20 @@ class DatagramSocket implements java.io.Closeable { // If the security check succeeds, or the datagram is // connected then receive the packet getImpl().receive(p); + if (explicitFilter && tmp == null) { + // packet was not filtered, account for it here + checkFiltering(p); + } + } + } + + private boolean checkFiltering(DatagramPacket p) throws SocketException { + bytesLeftToFilter -= p.getLength(); + if (bytesLeftToFilter <= 0 || getImpl().dataAvailable() <= 0) { + explicitFilter = false; + return true; } + return false; } /** diff --git a/src/share/classes/java/net/DatagramSocketImpl.java b/src/share/classes/java/net/DatagramSocketImpl.java index c2b1158f3d5853ae3257da4a7af604d097b523e2..537edfe9988fe7b340418e418e160df84a944334 100644 --- a/src/share/classes/java/net/DatagramSocketImpl.java +++ b/src/share/classes/java/net/DatagramSocketImpl.java @@ -47,6 +47,12 @@ public abstract class DatagramSocketImpl implements SocketOptions { */ protected FileDescriptor fd; + int dataAvailable() { + // default impl returns zero, which disables the calling + // functionality + return 0; + } + /** * The DatagramSocket or MulticastSocket * that owns this impl diff --git a/src/share/classes/java/security/Signature.java b/src/share/classes/java/security/Signature.java index 60a7e01b6c98805977d9f7c5c8b5689018855a1d..dccbe0b9b7e3d57b2130854e6ddaf06a67e2b1a6 100644 --- a/src/share/classes/java/security/Signature.java +++ b/src/share/classes/java/security/Signature.java @@ -615,6 +615,9 @@ public abstract class Signature extends SignatureSpi { if (outbuf == null) { throw new IllegalArgumentException("No output buffer given"); } + if (offset < 0 || len < 0) { + throw new IllegalArgumentException("offset or len is less than 0"); + } if (outbuf.length - offset < len) { throw new IllegalArgumentException ("Output buffer too small for specified offset and length"); @@ -683,9 +686,16 @@ public abstract class Signature extends SignatureSpi { public final boolean verify(byte[] signature, int offset, int length) throws SignatureException { if (state == VERIFY) { - if ((signature == null) || (offset < 0) || (length < 0) || - (length > signature.length - offset)) { - throw new IllegalArgumentException("Bad arguments"); + if (signature == null) { + throw new IllegalArgumentException("signature is null"); + } + if (offset < 0 || length < 0) { + throw new IllegalArgumentException + ("offset or length is less than 0"); + } + if (signature.length - offset < length) { + throw new IllegalArgumentException + ("signature too small for specified offset and length"); } return engineVerify(signature, offset, length); @@ -738,6 +748,16 @@ public abstract class Signature extends SignatureSpi { public final void update(byte[] data, int off, int len) throws SignatureException { if (state == SIGN || state == VERIFY) { + if (data == null) { + throw new IllegalArgumentException("data is null"); + } + if (off < 0 || len < 0) { + throw new IllegalArgumentException("off or len is less than 0"); + } + if (data.length - off < len) { + throw new IllegalArgumentException + ("data too small for specified offset and length"); + } engineUpdate(data, off, len); } else { throw new SignatureException("object not initialized for " diff --git a/src/share/classes/java/security/cert/CertificateRevokedException.java b/src/share/classes/java/security/cert/CertificateRevokedException.java index a545627061a49653882b47afc0a4da58e9c89e0f..505a007f5f2c782a78421d5eb821b22359e8fd82 100644 --- a/src/share/classes/java/security/cert/CertificateRevokedException.java +++ b/src/share/classes/java/security/cert/CertificateRevokedException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, 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,7 +94,10 @@ public class CertificateRevokedException extends CertificateException { this.revocationDate = new Date(revocationDate.getTime()); this.reason = reason; this.authority = authority; - this.extensions = new HashMap(extensions); + // make sure Map only contains correct types + this.extensions = Collections.checkedMap(new HashMap<>(), + String.class, Extension.class); + this.extensions.putAll(extensions); } /** @@ -172,7 +175,8 @@ public class CertificateRevokedException extends CertificateException { public String getMessage() { return "Certificate has been revoked, reason: " + reason + ", revocation date: " + revocationDate - + ", authority: " + authority + ", extensions: " + extensions; + + ", authority: " + authority + ", extension OIDs: " + + extensions.keySet(); } /** diff --git a/src/share/classes/java/util/ResourceBundle.java b/src/share/classes/java/util/ResourceBundle.java index d70b61ac89b9fbff18bf22ebf2d1fe45f3526ab8..134894ccdd1d1748d00050dfc8523bf53396866f 100644 --- a/src/share/classes/java/util/ResourceBundle.java +++ b/src/share/classes/java/util/ResourceBundle.java @@ -2650,7 +2650,10 @@ public abstract class ResourceBundle { } catch (ClassNotFoundException e) { } } else if (format.equals("java.properties")) { - final String resourceName = toResourceName(bundleName, "properties"); + final String resourceName = toResourceName0(bundleName, "properties"); + if (resourceName == null) { + return bundle; + } final ClassLoader classLoader = loader; final boolean reloadFlag = reload; InputStream stream = null; @@ -2804,7 +2807,10 @@ public abstract class ResourceBundle { } boolean result = false; try { - String resourceName = toResourceName(toBundleName(baseName, locale), format); + String resourceName = toResourceName0(toBundleName(baseName, locale), format); + if (resourceName == null) { + return result; + } URL url = loader.getResource(resourceName); if (url != null) { long lastModified = 0; @@ -2938,6 +2944,15 @@ public abstract class ResourceBundle { sb.append(bundleName.replace('.', '/')).append('.').append(suffix); return sb.toString(); } + + private String toResourceName0(String bundleName, String suffix) { + // application protocol check + if (bundleName.contains("://")) { + return null; + } else { + return toResourceName(bundleName, suffix); + } + } } private static class SingleFormatControl extends Control { diff --git a/src/share/classes/java/util/logging/LogRecord.java b/src/share/classes/java/util/logging/LogRecord.java index 50444f1cd8af2c88b0044ecd4f1613ff3d386659..d9255f42ea720cdc85e94b60186605061e2d0c5e 100644 --- a/src/share/classes/java/util/logging/LogRecord.java +++ b/src/share/classes/java/util/logging/LogRecord.java @@ -513,7 +513,13 @@ public class LogRecord implements java.io.Serializable { // If necessary, try to regenerate the resource bundle. if (resourceBundleName != null) { try { - resourceBundle = ResourceBundle.getBundle(resourceBundleName); + // use system class loader to ensure the ResourceBundle + // instance is a different instance than null loader uses + final ResourceBundle bundle = + ResourceBundle.getBundle(resourceBundleName, + Locale.getDefault(), + ClassLoader.getSystemClassLoader()); + resourceBundle = bundle; } catch (MissingResourceException ex) { // This is not a good place to throw an exception, // so we simply leave the resourceBundle null. diff --git a/src/share/classes/java/util/logging/Logger.java b/src/share/classes/java/util/logging/Logger.java index 90cbb87e1be5b875d1bf971e19b61eb8377fc768..4629320c1fdedc3a94dbf1766f802e87b8c00091 100644 --- a/src/share/classes/java/util/logging/Logger.java +++ b/src/share/classes/java/util/logging/Logger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, 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 @@ -1934,6 +1934,9 @@ public class Logger { } setCallersClassLoaderRef(callersClass); + if (isSystemLogger && getCallersClassLoader() != null) { + checkPermission(); + } if (findResourceBundle(name, true) == null) { // We've failed to find an expected ResourceBundle. // unset the caller's ClassLoader since we were unable to find the @@ -2168,11 +2171,13 @@ public class Logger { return trb; } final String rbName = isSystemLogger - ? trb.resourceBundleName + // ancestor of a system logger is expected to be a system logger. + // ignore resource bundle name if it's not. + ? (target.isSystemLogger ? trb.resourceBundleName : null) : target.getResourceBundleName(); if (rbName != null) { return LoggerBundle.get(rbName, - findResourceBundle(rbName, true)); + findResourceBundle(rbName, true)); } target = isSystemLogger ? target.parent : target.getParent(); } diff --git a/src/share/classes/javax/crypto/CipherInputStream.java b/src/share/classes/javax/crypto/CipherInputStream.java index 0e80a6013d5975aaa6f002b3db16ef5a9b0043f4..d777ca003d99a5f6b5b7f8e095ea22ab059ff441 100644 --- a/src/share/classes/javax/crypto/CipherInputStream.java +++ b/src/share/classes/javax/crypto/CipherInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, 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 @@ -88,6 +88,8 @@ public class CipherInputStream extends FilterInputStream { private int ofinish = 0; // stream status private boolean closed = false; + // The stream has been read from. False if the stream has never been read. + private boolean read = false; /** * private convenience function. @@ -103,13 +105,15 @@ public class CipherInputStream extends FilterInputStream { private int getMoreData() throws IOException { if (done) return -1; int readin = input.read(ibuffer); + read = true; if (readin == -1) { done = true; try { obuffer = cipher.doFinal(); + } catch (IllegalBlockSizeException | BadPaddingException e) { + obuffer = null; + throw new IOException(e); } - catch (IllegalBlockSizeException e) {obuffer = null;} - catch (BadPaddingException e) {obuffer = null;} if (obuffer == null) return -1; else { @@ -120,7 +124,10 @@ public class CipherInputStream extends FilterInputStream { } try { obuffer = cipher.update(ibuffer, 0, readin); - } catch (IllegalStateException e) {obuffer = null;}; + } catch (IllegalStateException e) { + obuffer = null; + throw e; + } ostart = 0; if (obuffer == null) ofinish = 0; @@ -308,6 +315,11 @@ public class CipherInputStream extends FilterInputStream { } } catch (BadPaddingException | IllegalBlockSizeException ex) { + /* If no data has been read from the stream to be en/decrypted, + we supress any exceptions, and close quietly. */ + if (read) { + throw new IOException(ex); + } } ostart = 0; ofinish = 0; diff --git a/src/share/classes/sun/awt/image/BytePackedRaster.java b/src/share/classes/sun/awt/image/BytePackedRaster.java index bd3835d5184507a6a11248fdd4c661527e7cd9dc..3e60f193ac209c4f7d79d8ba55d231ee55f58c88 100644 --- a/src/share/classes/sun/awt/image/BytePackedRaster.java +++ b/src/share/classes/sun/awt/image/BytePackedRaster.java @@ -1408,10 +1408,10 @@ public class BytePackedRaster extends SunWritableRaster { } } - int lastbit = (dataBitOffset - + (height-1) * scanlineStride * 8 - + (width-1) * pixelBitStride - + pixelBitStride - 1); + long lastbit = (long) dataBitOffset + + (long) (height - 1) * (long) scanlineStride * 8 + + (long) (width - 1) * (long) pixelBitStride + + (long) pixelBitStride - 1; if (lastbit < 0 || lastbit / 8 >= data.length) { throw new RasterFormatException("raster dimensions overflow " + "array bounds"); diff --git a/src/share/classes/sun/invoke/util/VerifyAccess.java b/src/share/classes/sun/invoke/util/VerifyAccess.java index a95aefbafb1e1feb608b63ef163303fa0f5b4121..fc870fc94037c2eb4c5688fb3f5906512fa643d7 100644 --- a/src/share/classes/sun/invoke/util/VerifyAccess.java +++ b/src/share/classes/sun/invoke/util/VerifyAccess.java @@ -102,19 +102,24 @@ public class VerifyAccess { case PUBLIC: return true; // already checked above case PROTECTED: + assert !defc.isInterface(); // protected members aren't allowed in interfaces if ((allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0 && isSamePackage(defc, lookupClass)) return true; if ((allowedModes & PROTECTED) == 0) return false; + // Protected members are accessible by subclasses, which does not include interfaces. + // Interfaces are types, not classes. They should not have access to + // protected members in j.l.Object, even though it is their superclass. if ((mods & STATIC) != 0 && !isRelatedClass(refc, lookupClass)) return false; if ((allowedModes & PROTECTED) != 0 && - isSuperClass(defc, lookupClass)) + isSubClass(lookupClass, defc)) return true; return false; case PACKAGE_ONLY: // That is, zero. Unmarked member is package-only access. + assert !defc.isInterface(); // package-private members aren't allowed in interfaces return ((allowedModes & PACKAGE_ALLOWED) != 0 && isSamePackage(defc, lookupClass)); case PRIVATE: @@ -129,12 +134,13 @@ public class VerifyAccess { static boolean isRelatedClass(Class refc, Class lookupClass) { return (refc == lookupClass || - refc.isAssignableFrom(lookupClass) || - lookupClass.isAssignableFrom(refc)); + isSubClass(refc, lookupClass) || + isSubClass(lookupClass, refc)); } - static boolean isSuperClass(Class defc, Class lookupClass) { - return defc.isAssignableFrom(lookupClass); + static boolean isSubClass(Class lookupClass, Class defc) { + return defc.isAssignableFrom(lookupClass) && + !lookupClass.isInterface(); // interfaces are types, not classes. } static int getClassModifiers(Class c) { diff --git a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java index a34286bddb418777b691d1756366627d1cc6ab31..53e84d434734b7058df9b4437aee367e9305fc7d 100644 --- a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java +++ b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java @@ -740,6 +740,26 @@ class DatagramChannelImpl // set or refresh local address localAddress = Net.localAddress(fd); + + // flush any packets already received. + boolean blocking = false; + synchronized (blockingLock()) { + try { + blocking = isBlocking(); + // remainder of each packet thrown away + ByteBuffer tmpBuf = ByteBuffer.allocate(1); + if (blocking) { + configureBlocking(false); + } + do { + tmpBuf.clear(); + } while (receive(tmpBuf) != null); + } finally { + if (blocking) { + configureBlocking(true); + } + } + } } } } diff --git a/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java b/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java index 6e73de70d52cfdf8e6225126eaa7e6c7b4d04ea2..120fe7aac16586991c6ce80110c086d7c4313457 100644 --- a/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java +++ b/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, 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,7 +29,6 @@ import java.lang.annotation.*; import java.lang.reflect.*; import java.io.Serializable; import java.util.*; -import java.lang.annotation.*; import java.security.AccessController; import java.security.PrivilegedAction; @@ -45,6 +44,11 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { private final Map memberValues; AnnotationInvocationHandler(Class type, Map memberValues) { + Class[] superInterfaces = type.getInterfaces(); + if (!type.isAnnotation() || + superInterfaces.length != 1 || + superInterfaces[0] != java.lang.annotation.Annotation.class) + throw new AnnotationFormatError("Attempt to create proxy for a non-annotation type."); this.type = type; this.memberValues = memberValues; } @@ -57,13 +61,17 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { if (member.equals("equals") && paramTypes.length == 1 && paramTypes[0] == Object.class) return equalsImpl(args[0]); - assert paramTypes.length == 0; - if (member.equals("toString")) + if (paramTypes.length != 0) + throw new AssertionError("Too many parameters for an annotation method"); + + switch(member) { + case "toString": return toStringImpl(); - if (member.equals("hashCode")) + case "hashCode": return hashCodeImpl(); - if (member.equals("annotationType")) + case "annotationType": return type; + } // Handle annotation member accessors Object result = memberValues.get(member); @@ -129,7 +137,7 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { * Implementation of dynamicProxy.toString() */ private String toStringImpl() { - StringBuffer result = new StringBuffer(128); + StringBuilder result = new StringBuilder(128); result.append('@'); result.append(type.getName()); result.append('('); @@ -277,6 +285,7 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { new PrivilegedAction() { public Method[] run() { final Method[] mm = type.getDeclaredMethods(); + validateAnnotationMethods(mm); AccessibleObject.setAccessible(mm, true); return mm; } @@ -286,6 +295,94 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { } private transient volatile Method[] memberMethods = null; + /** + * Validates that a method is structurally appropriate for an + * annotation type. As of Java SE 8, annotation types cannot + * contain static methods and the declared methods of an + * annotation type must take zero arguments and there are + * restrictions on the return type. + */ + private void validateAnnotationMethods(Method[] memberMethods) { + /* + * Specification citations below are from JLS + * 9.6.1. Annotation Type Elements + */ + boolean valid = true; + for(Method method : memberMethods) { + /* + * "By virtue of the AnnotationTypeElementDeclaration + * production, a method declaration in an annotation type + * declaration cannot have formal parameters, type + * parameters, or a throws clause. + * + * "By virtue of the AnnotationTypeElementModifier + * production, a method declaration in an annotation type + * declaration cannot be default or static." + */ + if (method.getModifiers() != (Modifier.PUBLIC | Modifier.ABSTRACT) || + method.isDefault() || + method.getParameterCount() != 0 || + method.getExceptionTypes().length != 0) { + valid = false; + break; + } + + /* + * "It is a compile-time error if the return type of a + * method declared in an annotation type is not one of the + * following: a primitive type, String, Class, any + * parameterized invocation of Class, an enum type + * (section 8.9), an annotation type, or an array type + * (chapter 10) whose element type is one of the preceding + * types." + */ + Class returnType = method.getReturnType(); + if (returnType.isArray()) { + returnType = returnType.getComponentType(); + if (returnType.isArray()) { // Only single dimensional arrays + valid = false; + break; + } + } + + if (!((returnType.isPrimitive() && returnType != void.class) || + returnType == java.lang.String.class || + returnType == java.lang.Class.class || + returnType.isEnum() || + returnType.isAnnotation())) { + valid = false; + break; + } + + /* + * "It is a compile-time error if any method declared in an + * annotation type has a signature that is + * override-equivalent to that of any public or protected + * method declared in class Object or in the interface + * java.lang.annotation.Annotation." + * + * The methods in Object or Annotation meeting the other + * criteria (no arguments, contrained return type, etc.) + * above are: + * + * String toString() + * int hashCode() + * Class annotationType() + */ + String methodName = method.getName(); + if ((methodName.equals("toString") && returnType == java.lang.String.class) || + (methodName.equals("hashCode") && returnType == int.class) || + (methodName.equals("annotationType") && returnType == java.lang.Class.class)) { + valid = false; + break; + } + } + if (valid) + return; + else + throw new AnnotationFormatError("Malformed method on an annotation type"); + } + /** * Implementation of dynamicProxy.hashCode() */ @@ -330,7 +427,6 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); - // Check to make sure that types have not evolved incompatibly AnnotationType annotationType = null; @@ -343,7 +439,6 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { Map> memberTypes = annotationType.memberTypes(); - // If there are annotation members without values, that // situation is handled by the invoke method. for (Map.Entry memberValue : memberValues.entrySet()) { diff --git a/src/share/classes/sun/security/ssl/CipherSuite.java b/src/share/classes/sun/security/ssl/CipherSuite.java index 528b369b976d8f950155d1f3d5722d585fee8d7d..703517184c4154ee27e4a7c2ad3c9340bf90e9d7 100644 --- a/src/share/classes/sun/security/ssl/CipherSuite.java +++ b/src/share/classes/sun/security/ssl/CipherSuite.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, 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 @@ -968,7 +968,7 @@ final class CipherSuite implements Comparable { * 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, RC-4, 3DES-EDE. + * AES_128(GCM), AES_256, AES_128, 3DES-EDE, RC-4. * 3. Prefer the stronger MAC algorithm, in the order of SHA384, * SHA256, SHA, MD5. * 4. Prefer the better performance of key exchange and digital @@ -1055,18 +1055,6 @@ final class CipherSuite implements Comparable { add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA", 0x0032, --p, K_DHE_DSS, B_AES_128, T); - // RC-4 - add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", - 0xC007, --p, K_ECDHE_ECDSA, B_RC4_128, N); - add("TLS_ECDHE_RSA_WITH_RC4_128_SHA", - 0xC011, --p, K_ECDHE_RSA, B_RC4_128, N); - add("SSL_RSA_WITH_RC4_128_SHA", - 0x0005, --p, K_RSA, B_RC4_128, N); - add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA", - 0xC002, --p, K_ECDH_ECDSA, B_RC4_128, N); - add("TLS_ECDH_RSA_WITH_RC4_128_SHA", - 0xC00C, --p, K_ECDH_RSA, B_RC4_128, N); - // Cipher suites in GCM mode, see RFC 5288/5289. // // We may increase the priority of cipher suites in GCM mode when @@ -1127,6 +1115,17 @@ final class CipherSuite implements Comparable { add("SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", 0x0013, --p, K_DHE_DSS, B_3DES, N); + // RC-4 + add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", + 0xC007, --p, K_ECDHE_ECDSA, B_RC4_128, N); + add("TLS_ECDHE_RSA_WITH_RC4_128_SHA", + 0xC011, --p, K_ECDHE_RSA, B_RC4_128, N); + add("SSL_RSA_WITH_RC4_128_SHA", + 0x0005, --p, K_RSA, B_RC4_128, N); + add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA", + 0xC002, --p, K_ECDH_ECDSA, B_RC4_128, N); + add("TLS_ECDH_RSA_WITH_RC4_128_SHA", + 0xC00C, --p, K_ECDH_RSA, B_RC4_128, N); add("SSL_RSA_WITH_RC4_128_MD5", 0x0004, --p, K_RSA, B_RC4_128, N); @@ -1146,7 +1145,7 @@ final class CipherSuite implements Comparable { * 2. If a cipher suite has been obsoleted, we put it at the end of * the list. * 3. Prefer the stronger bulk cipher, in the order of AES_256, - * AES_128, RC-4, 3DES-EDE, DES, RC4_40, DES40, NULL. + * AES_128, 3DES-EDE, RC-4, DES, DES40, RC4_40, NULL. * 4. Prefer the stronger MAC algorithm, in the order of SHA384, * SHA256, SHA, MD5. * 5. Prefer the better performance of key exchange and digital @@ -1174,32 +1173,15 @@ final class CipherSuite implements Comparable { add("TLS_DH_anon_WITH_AES_128_CBC_SHA", 0x0034, --p, K_DH_ANON, B_AES_128, N); - add("TLS_ECDH_anon_WITH_RC4_128_SHA", - 0xC016, --p, K_ECDH_ANON, B_RC4_128, N); - add("SSL_DH_anon_WITH_RC4_128_MD5", - 0x0018, --p, K_DH_ANON, B_RC4_128, N); - add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", 0xC017, --p, K_ECDH_ANON, B_3DES, N); add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", 0x001b, --p, K_DH_ANON, B_3DES, N); - add("TLS_RSA_WITH_NULL_SHA256", - 0x003b, --p, K_RSA, B_NULL, N, max, tls12, P_SHA256); - add("TLS_ECDHE_ECDSA_WITH_NULL_SHA", - 0xC006, --p, K_ECDHE_ECDSA, B_NULL, N); - add("TLS_ECDHE_RSA_WITH_NULL_SHA", - 0xC010, --p, K_ECDHE_RSA, B_NULL, N); - add("SSL_RSA_WITH_NULL_SHA", - 0x0002, --p, K_RSA, B_NULL, N); - add("TLS_ECDH_ECDSA_WITH_NULL_SHA", - 0xC001, --p, K_ECDH_ECDSA, B_NULL, N); - add("TLS_ECDH_RSA_WITH_NULL_SHA", - 0xC00B, --p, K_ECDH_RSA, B_NULL, N); - add("TLS_ECDH_anon_WITH_NULL_SHA", - 0xC015, --p, K_ECDH_ANON, B_NULL, N); - add("SSL_RSA_WITH_NULL_MD5", - 0x0001, --p, K_RSA, B_NULL, N); + add("TLS_ECDH_anon_WITH_RC4_128_SHA", + 0xC016, --p, K_ECDH_ANON, B_RC4_128, N); + add("SSL_DH_anon_WITH_RC4_128_MD5", + 0x0018, --p, K_DH_ANON, B_RC4_128, N); // weak cipher suites obsoleted in TLS 1.2 add("SSL_RSA_WITH_DES_CBC_SHA", @@ -1212,11 +1194,6 @@ final class CipherSuite implements Comparable { 0x001a, --p, K_DH_ANON, B_DES, N, tls12); // weak cipher suites obsoleted in TLS 1.1 - add("SSL_RSA_EXPORT_WITH_RC4_40_MD5", - 0x0003, --p, K_RSA_EXPORT, B_RC4_40, N, tls11); - add("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", - 0x0017, --p, K_DH_ANON, B_RC4_40, N, tls11); - add("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x0008, --p, K_RSA_EXPORT, B_DES_40, N, tls11); add("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", @@ -1226,27 +1203,49 @@ final class CipherSuite implements Comparable { add("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", 0x0019, --p, K_DH_ANON, B_DES_40, N, tls11); + add("SSL_RSA_EXPORT_WITH_RC4_40_MD5", + 0x0003, --p, K_RSA_EXPORT, B_RC4_40, N, tls11); + add("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", + 0x0017, --p, K_DH_ANON, B_RC4_40, N, tls11); + + add("TLS_RSA_WITH_NULL_SHA256", + 0x003b, --p, K_RSA, B_NULL, N, max, tls12, P_SHA256); + add("TLS_ECDHE_ECDSA_WITH_NULL_SHA", + 0xC006, --p, K_ECDHE_ECDSA, B_NULL, N); + add("TLS_ECDHE_RSA_WITH_NULL_SHA", + 0xC010, --p, K_ECDHE_RSA, B_NULL, N); + add("SSL_RSA_WITH_NULL_SHA", + 0x0002, --p, K_RSA, B_NULL, N); + add("TLS_ECDH_ECDSA_WITH_NULL_SHA", + 0xC001, --p, K_ECDH_ECDSA, B_NULL, N); + add("TLS_ECDH_RSA_WITH_NULL_SHA", + 0xC00B, --p, K_ECDH_RSA, B_NULL, N); + add("TLS_ECDH_anon_WITH_NULL_SHA", + 0xC015, --p, K_ECDH_ANON, B_NULL, N); + add("SSL_RSA_WITH_NULL_MD5", + 0x0001, --p, K_RSA, B_NULL, N); + // Supported Kerberos ciphersuites from RFC2712 - add("TLS_KRB5_WITH_RC4_128_SHA", - 0x0020, --p, K_KRB5, B_RC4_128, N); - add("TLS_KRB5_WITH_RC4_128_MD5", - 0x0024, --p, K_KRB5, B_RC4_128, N); add("TLS_KRB5_WITH_3DES_EDE_CBC_SHA", 0x001f, --p, K_KRB5, B_3DES, N); add("TLS_KRB5_WITH_3DES_EDE_CBC_MD5", 0x0023, --p, K_KRB5, B_3DES, N); + add("TLS_KRB5_WITH_RC4_128_SHA", + 0x0020, --p, K_KRB5, B_RC4_128, N); + add("TLS_KRB5_WITH_RC4_128_MD5", + 0x0024, --p, K_KRB5, B_RC4_128, N); add("TLS_KRB5_WITH_DES_CBC_SHA", 0x001e, --p, K_KRB5, B_DES, N, tls12); add("TLS_KRB5_WITH_DES_CBC_MD5", 0x0022, --p, K_KRB5, B_DES, N, tls12); - add("TLS_KRB5_EXPORT_WITH_RC4_40_SHA", - 0x0028, --p, K_KRB5_EXPORT, B_RC4_40, N, tls11); - add("TLS_KRB5_EXPORT_WITH_RC4_40_MD5", - 0x002b, --p, K_KRB5_EXPORT, B_RC4_40, N, tls11); add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", 0x0026, --p, K_KRB5_EXPORT, B_DES_40, N, tls11); add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", 0x0029, --p, K_KRB5_EXPORT, B_DES_40, N, tls11); + add("TLS_KRB5_EXPORT_WITH_RC4_40_SHA", + 0x0028, --p, K_KRB5_EXPORT, B_RC4_40, N, tls11); + add("TLS_KRB5_EXPORT_WITH_RC4_40_MD5", + 0x002b, --p, K_KRB5_EXPORT, B_RC4_40, N, tls11); /* * Other values from the TLS Cipher Suite Registry, as of August 2010. diff --git a/src/share/classes/sun/security/ssl/ClientHandshaker.java b/src/share/classes/sun/security/ssl/ClientHandshaker.java index 5c3abbcdab5b8641b2751f274bf86b7a2dea27dc..5108528f283b42d7b4806b935b5f967f308da7df 100644 --- a/src/share/classes/sun/security/ssl/ClientHandshaker.java +++ b/src/share/classes/sun/security/ssl/ClientHandshaker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, 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 @@ -36,6 +36,8 @@ import java.security.spec.ECParameterSpec; import java.security.cert.X509Certificate; import java.security.cert.CertificateException; +import java.security.cert.CertificateParsingException; +import javax.security.auth.x500.X500Principal; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; @@ -89,11 +91,65 @@ final class ClientHandshaker extends Handshaker { private final static boolean enableSNIExtension = Debug.getBooleanProperty("jsse.enableSNIExtension", true); + /* + * Allow unsafe server certificate change? + * + * Server certificate change during SSL/TLS renegotiation may be considered + * unsafe, as described in the Triple Handshake attacks: + * + * https://secure-resumption.com/tlsauth.pdf + * + * Endpoint identification (See + * SSLParameters.getEndpointIdentificationAlgorithm()) is a pretty nice + * guarantee that the server certificate change in renegotiation is legal. + * However, endpoing identification is only enabled for HTTPS and LDAP + * over SSL/TLS by default. It is not enough to protect SSL/TLS + * connections other than HTTPS and LDAP. + * + * The renegotiation indication extension (See RFC 5764) is a pretty + * strong guarantee that the endpoints on both client and server sides + * are identical on the same connection. However, the Triple Handshake + * attacks can bypass this guarantee if there is a session-resumption + * handshake between the initial full handshake and the renegotiation + * full handshake. + * + * Server certificate change may be unsafe and should be restricted if + * endpoint identification is not enabled and the previous handshake is + * a session-resumption abbreviated initial handshake, unless the + * identities represented by both certificates can be regraded as the + * same (See isIdentityEquivalent()). + * + * Considering the compatibility impact and the actual requirements to + * support server certificate change in practice, the system property, + * jdk.tls.allowUnsafeServerCertChange, is used to define whether unsafe + * server certificate change in renegotiation is allowed or not. The + * default value of the system property is "false". To mitigate the + * compactibility impact, applications may want to set the system + * property to "true" at their own risk. + * + * If the value of the system property is "false", server certificate + * change in renegotiation after a session-resumption abbreviated initial + * handshake is restricted (See isIdentityEquivalent()). + * + * If the system property is set to "true" explicitly, the restriction on + * server certificate change in renegotiation is disabled. + */ + private final static boolean allowUnsafeServerCertChange = + Debug.getBooleanProperty("jdk.tls.allowUnsafeServerCertChange", false); + private List requestedServerNames = Collections.emptyList(); private boolean serverNamesAccepted = false; + /* + * the reserved server certificate chain in previous handshaking + * + * The server certificate chain is only reserved if the previous + * handshake is a session-resumption abbreviated initial handshake. + */ + private X509Certificate[] reservedServerCerts = null; + /* * Constructors */ @@ -555,14 +611,19 @@ final class ClientHandshaker extends Handshaker { // we wanted to resume, but the server refused session = null; if (!enableNewSession) { - throw new SSLException - ("New session creation is disabled"); + throw new SSLException("New session creation is disabled"); } } } if (resumingSession && session != null) { setHandshakeSessionSE(session); + // Reserve the handshake state if this is a session-resumption + // abbreviated initial handshake. + if (isInitialHandshake) { + session.setAsSessionResumption(true); + } + return; } @@ -1063,6 +1124,13 @@ final class ClientHandshaker extends Handshaker { serverVerifyData = mesg.getVerifyData(); } + /* + * Reset the handshake state if this is not an initial handshake. + */ + if (!isInitialHandshake) { + session.setAsSessionResumption(false); + } + /* * OK, it verified. If we're doing the fast handshake, add that * "Finished" message to the hash of handshake messages, then send @@ -1161,8 +1229,23 @@ final class ClientHandshaker extends Handshaker { System.out.println("%% No cached client session"); } } - if ((session != null) && (session.isRejoinable() == false)) { - session = null; + if (session != null) { + // If unsafe server certificate change is not allowed, reserve + // current server certificates if the previous handshake is a + // session-resumption abbreviated initial handshake. + if (!allowUnsafeServerCertChange && session.isSessionResumption()) { + try { + // If existing, peer certificate chain cannot be null. + reservedServerCerts = + (X509Certificate[])session.getPeerCertificates(); + } catch (SSLPeerUnverifiedException puve) { + // Maybe not certificate-based, ignore the exception. + } + } + + if (!session.isRejoinable()) { + session = null; + } } if (session != null) { @@ -1331,9 +1414,28 @@ final class ClientHandshaker extends Handshaker { } X509Certificate[] peerCerts = mesg.getCertificateChain(); if (peerCerts.length == 0) { - fatalSE(Alerts.alert_bad_certificate, - "empty certificate chain"); + fatalSE(Alerts.alert_bad_certificate, "empty certificate chain"); + } + + // Allow server certificate change in client side during renegotiation + // after a session-resumption abbreviated initial handshake? + // + // DO NOT need to check allowUnsafeServerCertChange here. We only + // reserve server certificates when allowUnsafeServerCertChange is + // flase. + if (reservedServerCerts != null) { + // It is not necessary to check the certificate update if endpoint + // identification is enabled. + String identityAlg = getEndpointIdentificationAlgorithmSE(); + if ((identityAlg == null || identityAlg.length() == 0) && + !isIdentityEquivalent(peerCerts[0], reservedServerCerts[0])) { + + fatalSE(Alerts.alert_bad_certificate, + "server certificate change is restricted " + + "during renegotiation"); + } } + // ask the trust manager to verify the chain X509TrustManager tm = sslContext.getX509TrustManager(); try { @@ -1370,4 +1472,81 @@ final class ClientHandshaker extends Handshaker { } session.setPeerCertificates(peerCerts); } + + /* + * Whether the certificates can represent the same identity? + * + * The certificates can be used to represent the same identity: + * 1. If the subject alternative names of IP address are present in + * both certificates, they should be identical; otherwise, + * 2. if the subject alternative names of DNS name are present in + * both certificates, they should be identical; otherwise, + * 3. if the subject fields are present in both certificates, the + * certificate subjects and issuers should be identical. + */ + private static boolean isIdentityEquivalent(X509Certificate thisCert, + X509Certificate prevCert) { + if (thisCert.equals(prevCert)) { + return true; + } + + // check the iPAddress field in subjectAltName extension + Object thisIPAddress = getSubjectAltName(thisCert, 7); // 7: iPAddress + Object prevIPAddress = getSubjectAltName(prevCert, 7); + if (thisIPAddress != null && prevIPAddress!= null) { + // only allow the exactly match + return Objects.equals(thisIPAddress, prevIPAddress); + } + + // check the dNSName field in subjectAltName extension + Object thisDNSName = getSubjectAltName(thisCert, 2); // 2: dNSName + Object prevDNSName = getSubjectAltName(prevCert, 2); + if (thisDNSName != null && prevDNSName!= null) { + // only allow the exactly match + return Objects.equals(thisDNSName, prevDNSName); + } + + // check the certificate subject and issuer + X500Principal thisSubject = thisCert.getSubjectX500Principal(); + X500Principal prevSubject = prevCert.getSubjectX500Principal(); + X500Principal thisIssuer = thisCert.getIssuerX500Principal(); + X500Principal prevIssuer = prevCert.getIssuerX500Principal(); + if (!thisSubject.getName().isEmpty() && + !prevSubject.getName().isEmpty() && + thisSubject.equals(prevSubject) && + thisIssuer.equals(prevIssuer)) { + return true; + } + + return false; + } + + /* + * Returns the subject alternative name of the specified type in the + * subjectAltNames extension of a certificate. + */ + private static Object getSubjectAltName(X509Certificate cert, int type) { + Collection> subjectAltNames; + + try { + subjectAltNames = cert.getSubjectAlternativeNames(); + } catch (CertificateParsingException cpe) { + if (debug != null && Debug.isOn("handshake")) { + System.out.println( + "Attempt to obtain subjectAltNames extension failed!"); + } + return null; + } + + if (subjectAltNames != null) { + for (List subjectAltName : subjectAltNames) { + int subjectAltNameType = (Integer)subjectAltName.get(0); + if (subjectAltNameType == type) { + return subjectAltName.get(1); + } + } + } + + return null; + } } diff --git a/src/share/classes/sun/security/ssl/Handshaker.java b/src/share/classes/sun/security/ssl/Handshaker.java index bea8608e6ff4bde3da6ef6c2b23b64292697aef7..80c2a518c1bbbc623c23169c5778dff7146411c3 100644 --- a/src/share/classes/sun/security/ssl/Handshaker.java +++ b/src/share/classes/sun/security/ssl/Handshaker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, 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 @@ -359,6 +359,17 @@ abstract class Handshaker { } } + String getEndpointIdentificationAlgorithmSE() { + SSLParameters paras; + if (conn != null) { + paras = conn.getSSLParameters(); + } else { + paras = engine.getSSLParameters(); + } + + return paras.getEndpointIdentificationAlgorithm(); + } + private void setVersionSE(ProtocolVersion protocolVersion) { if (conn != null) { conn.setVersion(protocolVersion); diff --git a/src/share/classes/sun/security/ssl/SSLSessionImpl.java b/src/share/classes/sun/security/ssl/SSLSessionImpl.java index 6cb4170d34f2d012adaa4e666770ba9e5c354b28..b5f304b6b97e99e4b89f8cbd336a9b8878b4401e 100644 --- a/src/share/classes/sun/security/ssl/SSLSessionImpl.java +++ b/src/share/classes/sun/security/ssl/SSLSessionImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -114,6 +114,14 @@ final class SSLSessionImpl extends ExtendedSSLSession { private Principal peerPrincipal; private Principal localPrincipal; + /* + * Is the session currently re-established with a session-resumption + * abbreviated initial handshake? + * + * Note that currently we only set this variable in client side. + */ + private boolean isSessionResumption = false; + /* * We count session creations, eventually for statistical data but * also since counters make shorter debugging IDs than the big ones @@ -324,6 +332,22 @@ final class SSLSessionImpl extends ExtendedSSLSession { } } + /** + * Return true if the session is currently re-established with a + * session-resumption abbreviated initial handshake. + */ + boolean isSessionResumption() { + return isSessionResumption; + } + + /** + * Resets whether the session is re-established with a session-resumption + * abbreviated initial handshake. + */ + void setAsSessionResumption(boolean flag) { + isSessionResumption = flag; + } + /** * Returns the name of the cipher suite in use on this session */ diff --git a/src/share/classes/sun/util/locale/BaseLocale.java b/src/share/classes/sun/util/locale/BaseLocale.java index 6eee582909572d513f765b8e6e38f8a63bca6312..e0e9ed060928eebd35738276c3854f1c959931c5 100644 --- a/src/share/classes/sun/util/locale/BaseLocale.java +++ b/src/share/classes/sun/util/locale/BaseLocale.java @@ -31,6 +31,7 @@ */ package sun.util.locale; +import java.lang.ref.SoftReference; public final class BaseLocale { @@ -163,11 +164,11 @@ public final class BaseLocale { return h; } - private static final class Key implements Comparable { - private final String lang; - private final String scrt; - private final String regn; - private final String vart; + private static final class Key { + private final SoftReference lang; + private final SoftReference scrt; + private final SoftReference regn; + private final SoftReference vart; private final boolean normalized; private final int hash; @@ -179,10 +180,10 @@ public final class BaseLocale { assert language.intern() == language && region.intern() == region; - lang = language; - scrt = ""; - regn = region; - vart = ""; + lang = new SoftReference(language); + scrt = new SoftReference(""); + regn = new SoftReference(region); + vart = new SoftReference(""); this.normalized = true; int h = language.hashCode(); @@ -203,40 +204,40 @@ public final class BaseLocale { String variant, boolean normalized) { int h = 0; if (language != null) { - lang = language; + lang = new SoftReference(language); int len = language.length(); for (int i = 0; i < len; i++) { h = 31*h + LocaleUtils.toLower(language.charAt(i)); } } else { - lang = ""; + lang = new SoftReference(""); } if (script != null) { - scrt = script; + scrt = new SoftReference(script); int len = script.length(); for (int i = 0; i < len; i++) { h = 31*h + LocaleUtils.toLower(script.charAt(i)); } } else { - scrt = ""; + scrt = new SoftReference(""); } if (region != null) { - regn = region; + regn = new SoftReference(region); int len = region.length(); for (int i = 0; i < len; i++) { h = 31*h + LocaleUtils.toLower(region.charAt(i)); } } else { - regn = ""; + regn = new SoftReference(""); } if (variant != null) { - vart = variant; + vart = new SoftReference(variant); int len = variant.length(); for (int i = 0; i < len; i++) { h = 31*h + variant.charAt(i); } } else { - vart = ""; + vart = new SoftReference(""); } hash = h; this.normalized = normalized; @@ -244,28 +245,31 @@ public final class BaseLocale { @Override public boolean equals(Object obj) { - return (this == obj) || - (obj instanceof Key) - && this.hash == ((Key)obj).hash - && LocaleUtils.caseIgnoreMatch(((Key)obj).lang, this.lang) - && LocaleUtils.caseIgnoreMatch(((Key)obj).scrt, this.scrt) - && LocaleUtils.caseIgnoreMatch(((Key)obj).regn, this.regn) - && ((Key)obj).vart.equals(vart); // variant is case sensitive in JDK! + if (this == obj) { + return true; } - @Override - public int compareTo(Key other) { - int res = LocaleUtils.caseIgnoreCompare(this.lang, other.lang); - if (res == 0) { - res = LocaleUtils.caseIgnoreCompare(this.scrt, other.scrt); - if (res == 0) { - res = LocaleUtils.caseIgnoreCompare(this.regn, other.regn); - if (res == 0) { - res = this.vart.compareTo(other.vart); + if (obj instanceof Key && this.hash == ((Key)obj).hash) { + String tl = this.lang.get(); + String ol = ((Key)obj).lang.get(); + if (tl != null && ol != null && + LocaleUtils.caseIgnoreMatch(ol, tl)) { + String ts = this.scrt.get(); + String os = ((Key)obj).scrt.get(); + if (ts != null && os != null && + LocaleUtils.caseIgnoreMatch(os, ts)) { + String tr = this.regn.get(); + String or = ((Key)obj).regn.get(); + if (tr != null && or != null && + LocaleUtils.caseIgnoreMatch(or, tr)) { + String tv = this.vart.get(); + String ov = ((Key)obj).vart.get(); + return (ov != null && ov.equals(tv)); } } } - return res; + } + return false; } @Override @@ -278,10 +282,10 @@ public final class BaseLocale { return key; } - String lang = LocaleUtils.toLowerString(key.lang).intern(); - String scrt = LocaleUtils.toTitleString(key.scrt).intern(); - String regn = LocaleUtils.toUpperString(key.regn).intern(); - String vart = key.vart.intern(); // preserve upper/lower cases + String lang = LocaleUtils.toLowerString(key.lang.get()).intern(); + String scrt = LocaleUtils.toTitleString(key.scrt.get()).intern(); + String regn = LocaleUtils.toUpperString(key.regn.get()).intern(); + String vart = key.vart.get().intern(); // preserve upper/lower cases return new Key(lang, scrt, regn, vart, true); } @@ -294,12 +298,18 @@ public final class BaseLocale { @Override protected Key normalizeKey(Key key) { + assert key.lang.get() != null && + key.scrt.get() != null && + key.regn.get() != null && + key.vart.get() != null; + return Key.normalize(key); } @Override protected BaseLocale createObject(Key key) { - return new BaseLocale(key.lang, key.scrt, key.regn, key.vart); + return new BaseLocale(key.lang.get(), key.scrt.get(), + key.regn.get(), key.vart.get()); } } } diff --git a/src/share/classes/sun/util/locale/LocaleObjectCache.java b/src/share/classes/sun/util/locale/LocaleObjectCache.java index 88920aaf50c07806282a0731bb8d85d09a664358..eae1480882b96d2810f20978db366319202815e3 100644 --- a/src/share/classes/sun/util/locale/LocaleObjectCache.java +++ b/src/share/classes/sun/util/locale/LocaleObjectCache.java @@ -57,8 +57,10 @@ public abstract class LocaleObjectCache { value = entry.get(); } if (value == null) { - key = normalizeKey(key); V newVal = createObject(key); + // make sure key is normalized *after* the object creation + // so that newVal is assured to be created from a valid key. + key = normalizeKey(key); if (key == null || newVal == null) { // subclass must return non-null key/value object return null; diff --git a/src/share/javavm/export/jvm.h b/src/share/javavm/export/jvm.h index 396ca68558e20b3023db6c55809fa23cbe0db769..1aaec31c3226b1019c43ffccef79c701ba45e757 100644 --- a/src/share/javavm/export/jvm.h +++ b/src/share/javavm/export/jvm.h @@ -385,6 +385,19 @@ JVM_ResolveClass(JNIEnv *env, jclass cls); JNIEXPORT jclass JNICALL JVM_FindClassFromBootLoader(JNIEnv *env, const char *name); +/* + * Find a class from a given class loader. Throws ClassNotFoundException. + * name: name of class + * init: whether initialization is done + * loader: class loader to look up the class. This may not be the same as the caller's + * class loader. + * caller: initiating class. The initiating class may be null when a security + * manager is not installed. + */ +JNIEXPORT jclass JNICALL +JVM_FindClassFromCaller(JNIEnv *env, const char *name, jboolean init, + jobject loader, jclass caller); + /* * Find a class from a given class loader. Throw ClassNotFoundException * or NoClassDefFoundError depending on the value of the last diff --git a/src/share/native/java/lang/Class.c b/src/share/native/java/lang/Class.c index c5e717fe0df57c6736376189aa5c8d980ae16ba3..b80b71786d2690a2b8d12a1304303e317d15b91d 100644 --- a/src/share/native/java/lang/Class.c +++ b/src/share/native/java/lang/Class.c @@ -94,7 +94,7 @@ Java_java_lang_Class_registerNatives(JNIEnv *env, jclass cls) JNIEXPORT jclass JNICALL Java_java_lang_Class_forName0(JNIEnv *env, jclass this, jstring classname, - jboolean initialize, jobject loader) + jboolean initialize, jobject loader, jclass caller) { char *clname; jclass cls = 0; @@ -132,8 +132,7 @@ Java_java_lang_Class_forName0(JNIEnv *env, jclass this, jstring classname, goto done; } - cls = JVM_FindClassFromClassLoader(env, clname, initialize, - loader, JNI_FALSE); + cls = JVM_FindClassFromCaller(env, clname, initialize, loader, caller); done: if (clname != buf) { diff --git a/src/share/native/java/util/zip/CRC32.c b/src/share/native/java/util/zip/CRC32.c index e9185b5fb1bc577b35f547507ebc73a3af9fb055..b03b2b9c53c7380fa34556a174da822cc49e1379 100644 --- a/src/share/native/java/util/zip/CRC32.c +++ b/src/share/native/java/util/zip/CRC32.c @@ -54,7 +54,8 @@ Java_java_util_zip_CRC32_updateBytes(JNIEnv *env, jclass cls, jint crc, return crc; } -JNIEXPORT jint ZIP_CRC32(jint crc, const jbyte *buf, jint len) +JNIEXPORT jint JNICALL +ZIP_CRC32(jint crc, const jbyte *buf, jint len) { return crc32(crc, (Bytef*)buf, len); } diff --git a/src/share/native/java/util/zip/ZipFile.c b/src/share/native/java/util/zip/ZipFile.c index e2916c23584d4743053f443bf030ebd04535cd38..7b34f66a2483a462b8aea9f02b22a79e357f9840 100644 --- a/src/share/native/java/util/zip/ZipFile.c +++ b/src/share/native/java/util/zip/ZipFile.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -172,11 +172,7 @@ Java_java_util_zip_ZipFile_getEntry(JNIEnv *env, jclass cls, jlong zfile, } (*env)->GetByteArrayRegion(env, name, 0, ulen, (jbyte *)path); path[ulen] = '\0'; - if (addSlash == JNI_FALSE) { - ze = ZIP_GetEntry(zip, path, 0); - } else { - ze = ZIP_GetEntry(zip, path, (jint)ulen); - } + ze = ZIP_GetEntry2(zip, path, (jint)ulen, addSlash); if (path != buf) { free(path); } @@ -269,7 +265,7 @@ Java_java_util_zip_ZipFile_getEntryBytes(JNIEnv *env, switch (type) { case java_util_zip_ZipFile_JZENTRY_NAME: if (ze->name != 0) { - len = (int)strlen(ze->name); + len = (int)ze->nlen; if (len == 0 || (jba = (*env)->NewByteArray(env, len)) == NULL) break; (*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte *)ze->name); diff --git a/src/share/native/java/util/zip/zip_util.c b/src/share/native/java/util/zip/zip_util.c index a072e6624c4e707896fb89794654e802baaeac62..b172cde31729f67a54ea2bfeffdeda7c5a97c708 100644 --- a/src/share/native/java/util/zip/zip_util.c +++ b/src/share/native/java/util/zip/zip_util.c @@ -1021,6 +1021,7 @@ newEntry(jzfile *zip, jzcell *zc, AccessHint accessHint) if ((ze->name = malloc(nlen + 1)) == NULL) goto Catch; memcpy(ze->name, cen + CENHDR, nlen); ze->name[nlen] = '\0'; + ze->nlen = nlen; if (elen > 0) { char *extra = cen + CENHDR + nlen; @@ -1118,7 +1119,34 @@ ZIP_FreeEntry(jzfile *jz, jzentry *ze) jzentry * ZIP_GetEntry(jzfile *zip, char *name, jint ulen) { - unsigned int hsh = hash(name); + if (ulen == 0) { + return ZIP_GetEntry2(zip, name, strlen(name), JNI_FALSE); + } + return ZIP_GetEntry2(zip, name, ulen, JNI_TRUE); +} + +jboolean equals(char* name1, int len1, char* name2, int len2) { + if (len1 != len2) { + return JNI_FALSE; + } + while (len1-- > 0) { + if (*name1++ != *name2++) { + return JNI_FALSE; + } + } + return JNI_TRUE; +} + +/* + * Returns the zip entry corresponding to the specified name, or + * NULL if not found. + * This method supports embedded null character in "name", use ulen + * for the length of "name". + */ +jzentry * +ZIP_GetEntry2(jzfile *zip, char *name, jint ulen, jboolean addSlash) +{ + unsigned int hsh = hashN(name, ulen); jint idx; jzentry *ze = 0; @@ -1139,7 +1167,7 @@ ZIP_GetEntry(jzfile *zip, char *name, jint ulen) /* Check the cached entry first */ ze = zip->cache; - if (ze && strcmp(ze->name,name) == 0) { + if (ze && equals(ze->name, ze->nlen, name, ulen)) { /* Cache hit! Remove and return the cached entry. */ zip->cache = 0; ZIP_Unlock(zip); @@ -1165,7 +1193,7 @@ ZIP_GetEntry(jzfile *zip, char *name, jint ulen) * we keep searching. */ ze = newEntry(zip, zc, ACCESS_RANDOM); - if (ze && strcmp(ze->name, name)==0) { + if (ze && equals(ze->name, ze->nlen, name, ulen)) { break; } if (ze != 0) { @@ -1184,8 +1212,8 @@ ZIP_GetEntry(jzfile *zip, char *name, jint ulen) break; } - /* If no real length was passed in, we are done */ - if (ulen == 0) { + /* If no need to try appending slash, we are done */ + if (!addSlash) { break; } @@ -1195,11 +1223,11 @@ ZIP_GetEntry(jzfile *zip, char *name, jint ulen) } /* Add slash and try once more */ - name[ulen] = '/'; - name[ulen+1] = '\0'; + name[ulen++] = '/'; + name[ulen] = '\0'; hsh = hash_append(hsh, '/'); idx = zip->table[hsh % zip->tablelen]; - ulen = 0; + addSlash = JNI_FALSE; } Finally: diff --git a/src/share/native/java/util/zip/zip_util.h b/src/share/native/java/util/zip/zip_util.h index a4aaf83823bb203f903c5cb045acd196916e714b..a64668cd6d994879f33fb0feddc7bae28dbd6962 100644 --- a/src/share/native/java/util/zip/zip_util.h +++ b/src/share/native/java/util/zip/zip_util.h @@ -154,6 +154,7 @@ * - If pos <= 0 then it is the position of entry LOC header. * If pos > 0 then it is the position of entry data. * pos should not be accessed directly, but only by ZIP_GetEntryDataOffset. + * - entry name may include embedded null character, use nlen for length */ typedef struct jzentry { /* Zip file entry */ @@ -166,6 +167,7 @@ typedef struct jzentry { /* Zip file entry */ jbyte *extra; /* optional extra data */ jlong pos; /* position of LOC header or entry data */ jint flag; /* general purpose flag */ + jint nlen; /* length of the entry name */ } jzentry; /* @@ -269,5 +271,5 @@ void ZIP_Unlock(jzfile *zip); jint ZIP_Read(jzfile *zip, jzentry *entry, jlong pos, void *buf, jint len); void ZIP_FreeEntry(jzfile *zip, jzentry *ze); jlong ZIP_GetEntryDataOffset(jzfile *zip, jzentry *entry); - +jzentry * ZIP_GetEntry2(jzfile *zip, char *name, jint ulen, jboolean addSlash); #endif /* !_ZIP_H_ */ diff --git a/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp b/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp index 3707efdfb4f0568e766ddd8daa76add892491739..e985b81cb53e643520baa9960dadb580d177bbdb 100644 --- a/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp +++ b/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp @@ -243,12 +243,22 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LETableReference le_uint16 srSetCount = SWAPW(subRuleSetCount); if (coverageIndex < srSetCount) { + LEReferenceToArrayOf subRuleSetTableOffsetArrayRef(base, success, + &subRuleSetTableOffsetArray[coverageIndex], 1); + if (LE_FAILURE(success)) { + return 0; + } Offset subRuleSetTableOffset = SWAPW(subRuleSetTableOffsetArray[coverageIndex]); LEReferenceTo subRuleSetTable(base, success, (const SubRuleSetTable *) ((char *) this + subRuleSetTableOffset)); le_uint16 subRuleCount = SWAPW(subRuleSetTable->subRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); + LEReferenceToArrayOf subRuleTableOffsetArrayRef(base, success, + subRuleSetTable->subRuleTableOffsetArray, subRuleCount); + if (LE_FAILURE(success)) { + return 0; + } for (le_uint16 subRule = 0; subRule < subRuleCount; subRule += 1) { Offset subRuleTableOffset = SWAPW(subRuleSetTable->subRuleTableOffsetArray[subRule]); @@ -301,13 +311,22 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LETableReference glyphIterator->getCurrGlyphID(), success); - if (setClass < scSetCount && subClassSetTableOffsetArray[setClass] != 0) { + if (setClass < scSetCount) { + LEReferenceToArrayOf + subClassSetTableOffsetArrayRef(base, success, subClassSetTableOffsetArray, setClass); + if (LE_FAILURE(success)) { return 0; } + if (subClassSetTableOffsetArray[setClass] != 0) { + Offset subClassSetTableOffset = SWAPW(subClassSetTableOffsetArray[setClass]); LEReferenceTo subClassSetTable(base, success, (const SubClassSetTable *) ((char *) this + subClassSetTableOffset)); le_uint16 subClassRuleCount = SWAPW(subClassSetTable->subClassRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); - + LEReferenceToArrayOf + subClassRuleTableOffsetArrayRef(base, success, subClassSetTable->subClassRuleTableOffsetArray, subClassRuleCount); + if (LE_FAILURE(success)) { + return 0; + } for (le_uint16 scRule = 0; scRule < subClassRuleCount; scRule += 1) { Offset subClassRuleTableOffset = SWAPW(subClassSetTable->subClassRuleTableOffsetArray[scRule]); @@ -331,6 +350,7 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LETableReference glyphIterator->setCurrStreamPosition(position); } } + } // XXX If we get here, the table is mal-formed... } @@ -442,13 +462,22 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LETableRe le_uint16 srSetCount = SWAPW(chainSubRuleSetCount); if (coverageIndex < srSetCount) { + LEReferenceToArrayOf + chainSubRuleSetTableOffsetArrayRef(base, success, chainSubRuleSetTableOffsetArray, coverageIndex); + if (LE_FAILURE(success)) { + return 0; + } Offset chainSubRuleSetTableOffset = SWAPW(chainSubRuleSetTableOffsetArray[coverageIndex]); LEReferenceTo chainSubRuleSetTable(base, success, (const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset)); le_uint16 chainSubRuleCount = SWAPW(chainSubRuleSetTable->chainSubRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); - + LEReferenceToArrayOf + chainSubRuleTableOffsetArrayRef(base, success, chainSubRuleSetTable->chainSubRuleTableOffsetArray, chainSubRuleCount); + if (LE_FAILURE(success)) { + return 0; + } for (le_uint16 subRule = 0; subRule < chainSubRuleCount; subRule += 1) { Offset chainSubRuleTableOffset = SWAPW(chainSubRuleSetTable->chainSubRuleTableOffsetArray[subRule]); @@ -530,6 +559,11 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LETableRe le_int32 setClass = inputClassDefinitionTable->getGlyphClass(inputClassDefinitionTable, glyphIterator->getCurrGlyphID(), success); + LEReferenceToArrayOf + chainSubClassSetTableOffsetArrayRef(base, success, chainSubClassSetTableOffsetArray, setClass); + if (LE_FAILURE(success)) { + return 0; + } if (setClass < scSetCount && chainSubClassSetTableOffsetArray[setClass] != 0) { Offset chainSubClassSetTableOffset = SWAPW(chainSubClassSetTableOffsetArray[setClass]); @@ -538,7 +572,11 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LETableRe le_uint16 chainSubClassRuleCount = SWAPW(chainSubClassSetTable->chainSubClassRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); - + LEReferenceToArrayOf + chainSubClassRuleTableOffsetArrayRef(base, success, chainSubClassSetTable->chainSubClassRuleTableOffsetArray, chainSubClassRuleCount); + if (LE_FAILURE(success)) { + return 0; + } for (le_uint16 scRule = 0; scRule < chainSubClassRuleCount; scRule += 1) { Offset chainSubClassRuleTableOffset = SWAPW(chainSubClassSetTable->chainSubClassRuleTableOffsetArray[scRule]); @@ -603,12 +641,14 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LETableRe } le_uint16 backtrkGlyphCount = SWAPW(backtrackGlyphCount); + LEReferenceToArrayOf backtrackGlyphArrayRef(base, success, backtrackCoverageTableOffsetArray, backtrkGlyphCount); + if (LE_FAILURE(success)) { + return 0; + } le_uint16 inputGlyphCount = (le_uint16) SWAPW(backtrackCoverageTableOffsetArray[backtrkGlyphCount]); LEReferenceToArrayOf inputCoverageTableOffsetArray(base, success, &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1], inputGlyphCount+2); // offset if (LE_FAILURE(success)) { return 0; } const le_uint16 lookaheadGlyphCount = (le_uint16) SWAPW(inputCoverageTableOffsetArray[inputGlyphCount]); - - if( LE_FAILURE(success)) { return 0; } LEReferenceToArrayOf lookaheadCoverageTableOffsetArray(base, success, inputCoverageTableOffsetArray.getAlias(inputGlyphCount + 1, success), lookaheadGlyphCount+2); if( LE_FAILURE(success) ) { return 0; } diff --git a/src/solaris/classes/sun/print/CUPSPrinter.java b/src/solaris/classes/sun/print/CUPSPrinter.java index c8f902090d9981582c6de681f80ee7088d3fc0f1..1a941d01449a6047c0ca6a4dcfc9178c56745a96 100644 --- a/src/solaris/classes/sun/print/CUPSPrinter.java +++ b/src/solaris/classes/sun/print/CUPSPrinter.java @@ -126,7 +126,7 @@ public class CUPSPrinter { /** * Returns array of MediaSizeNames derived from PPD. */ - public MediaSizeName[] getMediaSizeNames() { + MediaSizeName[] getMediaSizeNames() { initMedia(); return cupsMediaSNames; } @@ -135,7 +135,7 @@ public class CUPSPrinter { /** * Returns array of Custom MediaSizeNames derived from PPD. */ - public CustomMediaSizeName[] getCustomMediaSizeNames() { + CustomMediaSizeName[] getCustomMediaSizeNames() { initMedia(); return cupsCustomMediaSNames; } @@ -147,7 +147,7 @@ public class CUPSPrinter { /** * Returns array of MediaPrintableArea derived from PPD. */ - public MediaPrintableArea[] getMediaPrintableArea() { + MediaPrintableArea[] getMediaPrintableArea() { initMedia(); return cupsMediaPrintables; } @@ -155,7 +155,7 @@ public class CUPSPrinter { /** * Returns array of MediaTrays derived from PPD. */ - public MediaTray[] getMediaTrays() { + MediaTray[] getMediaTrays() { initMedia(); return cupsMediaTrays; } diff --git a/src/solaris/classes/sun/print/IPPPrintService.java b/src/solaris/classes/sun/print/IPPPrintService.java index 1be02c950052139e2b429775d3552dfb84ef9538..a355b17c7e39db9322eee4c465741237876f8050 100644 --- a/src/solaris/classes/sun/print/IPPPrintService.java +++ b/src/solaris/classes/sun/print/IPPPrintService.java @@ -994,7 +994,9 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { public synchronized Class[] getSupportedAttributeCategories() { if (supportedCats != null) { - return supportedCats; + Class [] copyCats = new Class[supportedCats.length]; + System.arraycopy(supportedCats, 0, copyCats, 0, copyCats.length); + return copyCats; } initAttributes(); @@ -1051,7 +1053,9 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { } supportedCats = new Class[catList.size()]; catList.toArray(supportedCats); - return supportedCats; + Class[] copyCats = new Class[supportedCats.length]; + System.arraycopy(supportedCats, 0, copyCats, 0, copyCats.length); + return copyCats; } diff --git a/src/solaris/native/java/net/AbstractPlainDatagramSocketImpl.c b/src/solaris/native/java/net/AbstractPlainDatagramSocketImpl.c new file mode 100644 index 0000000000000000000000000000000000000000..075fffc51768220067f35dc1644c3c6e09cf95f9 --- /dev/null +++ b/src/solaris/native/java/net/AbstractPlainDatagramSocketImpl.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2014, 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. + */ + +#include +#include + +#ifdef __solaris__ +#include +#include + +#ifndef BSD_COMP +#define BSD_COMP +#endif + +#endif + +#include + +#include "jvm.h" +#include "jni_util.h" +#include "net_util.h" + +#include "java_net_AbstractPlainDatagramSocketImpl.h" + +static jfieldID IO_fd_fdID; + +static jfieldID apdsi_fdID; + + +/* + * Class: java_net_AbstractPlainDatagramSocketImpl + * Method: init + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_java_net_AbstractPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) { + + apdsi_fdID = (*env)->GetFieldID(env, cls, "fd", + "Ljava/io/FileDescriptor;"); + CHECK_NULL(apdsi_fdID); + + IO_fd_fdID = NET_GetFileDescriptorID(env); +} + +/* + * Class: java_net_AbstractPlainDatagramSocketImpl + * Method: dataAvailable + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_java_net_AbstractPlainDatagramSocketImpl_dataAvailable +(JNIEnv *env, jobject this) { + int fd, retval; + + jobject fdObj = (*env)->GetObjectField(env, this, apdsi_fdID); + + if (IS_NULL(fdObj)) { + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", + "Socket closed"); + return -1; + } + fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID); + + if (ioctl(fd, FIONREAD, &retval) < 0) { + return -1; + } + return retval; +} diff --git a/src/windows/native/java/net/AbstractPlainDatagramSocketImpl.c b/src/windows/native/java/net/AbstractPlainDatagramSocketImpl.c new file mode 100644 index 0000000000000000000000000000000000000000..dd2c7e8a92fda8505df3e22cc927d750cd7e79fe --- /dev/null +++ b/src/windows/native/java/net/AbstractPlainDatagramSocketImpl.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2014, 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. + */ + +#include +#include + +#include "jvm.h" +#include "jni_util.h" +#include "net_util.h" + +#include "java_net_AbstractPlainDatagramSocketImpl.h" + +static jfieldID IO_fd_fdID = NULL; +static jfieldID apdsi_fdID = NULL; + +static jfieldID apdsi_fd1ID = NULL; +static jclass two_stacks_clazz = NULL; + + +/* + * Class: java_net_AbstractPlainDatagramSocketImpl + * Method: init + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_java_net_AbstractPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) { + + apdsi_fdID = (*env)->GetFieldID(env, cls, "fd", + "Ljava/io/FileDescriptor;"); + CHECK_NULL(apdsi_fdID); + IO_fd_fdID = NET_GetFileDescriptorID(env); + CHECK_NULL(IO_fd_fdID); + + two_stacks_clazz = (*env)->FindClass(env, "java/net/TwoStacksPlainDatagramSocketImpl"); + CHECK_NULL(two_stacks_clazz); + + /* Handle both TwoStacks and DualStack here */ + + if (JNU_Equals(env, cls, two_stacks_clazz)) { + /* fd1 present only in TwoStack.. */ + apdsi_fd1ID = (*env)->GetFieldID(env, cls, "fd1", + "Ljava/io/FileDescriptor;"); + CHECK_NULL(apdsi_fd1ID); + } + + JNU_CHECK_EXCEPTION(env); +} + +/* + * Class: java_net_AbstractPlainDatagramSocketImpl + * Method: dataAvailable + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_java_net_AbstractPlainDatagramSocketImpl_dataAvailable +(JNIEnv *env, jobject this) { + SOCKET fd; + SOCKET fd1; + int rv = -1, rv1 = -1; + jobject fdObj = (*env)->GetObjectField(env, this, apdsi_fdID); + + if (!IS_NULL(fdObj)) { + int retval = 0; + fd = (SOCKET)(*env)->GetIntField(env, fdObj, IO_fd_fdID); + rv = ioctlsocket(fd, FIONREAD, &retval); + if (retval > 0) { + return retval; + } + } + + if (!IS_NULL(apdsi_fd1ID)) { + /* TwoStacks */ + jobject fd1Obj = (*env)->GetObjectField(env, this, apdsi_fd1ID); + if (!IS_NULL(fd1Obj)) { + int retval = 0; + fd1 = (SOCKET)(*env)->GetIntField(env, fd1Obj, IO_fd_fdID); + rv1 = ioctlsocket(fd1, FIONREAD, &retval); + if (retval > 0) { + return retval; + } + } + } + + if (rv < 0 && rv1 < 0) { + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", + "Socket closed"); + return -1; + } + + return 0; +} + diff --git a/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c b/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c index ddbc00695f5d43b35764b048316f171e48576422..8e02c1869fa29fe1c7ad452963c8d85701eb6720 100644 --- a/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c +++ b/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, 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 @@ -213,6 +213,14 @@ SplashPaint(Splash * splash, HDC hdc) void SplashRedrawWindow(Splash * splash) { + if (!SplashIsStillLooping(splash)) { + KillTimer(splash->hWnd, 0); + } + + if (splash->currentFrame < 0) { + return; + } + SplashUpdateScreenData(splash); if (splash->isLayered) { BLENDFUNCTION bf; @@ -303,9 +311,6 @@ SplashRedrawWindow(Splash * splash) time = 0; SetTimer(splash->hWnd, 0, time, NULL); } - else { - KillTimer(splash->hWnd, 0); - } } void SplashReconfigureNow(Splash * splash) { diff --git a/test/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java b/test/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java index 12139f6bbdaece412d63bd7187c0aaca22f5ae53..a867e453389c825c4c979e88227ff7052025872a 100644 --- a/test/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java +++ b/test/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java @@ -23,7 +23,7 @@ /** * @test - * @bug 6476665 7033534 6830714 + * @bug 6476665 7033534 6830714 8052162 * @summary Verifies color conversion of Component Color Model based images * @run main ColConvCCMTest */ diff --git a/test/sun/security/ssl/sanity/ciphersuites/CipherSuitesInOrder.java b/test/sun/security/ssl/sanity/ciphersuites/CipherSuitesInOrder.java index 361ac8668031d82ba7b7d07f47d21581aea6bed5..69745aa7062442e80e75fb6d064f127d0b069d4f 100644 --- a/test/sun/security/ssl/sanity/ciphersuites/CipherSuitesInOrder.java +++ b/test/sun/security/ssl/sanity/ciphersuites/CipherSuitesInOrder.java @@ -69,11 +69,6 @@ public class CipherSuitesInOrder { "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_DSS_WITH_AES_128_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", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", @@ -97,6 +92,12 @@ public class CipherSuitesInOrder { "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", "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", @@ -110,38 +111,38 @@ public class CipherSuitesInOrder { "TLS_DH_anon_WITH_AES_128_CBC_SHA256", "TLS_ECDH_anon_WITH_AES_128_CBC_SHA", "TLS_DH_anon_WITH_AES_128_CBC_SHA", - "TLS_ECDH_anon_WITH_RC4_128_SHA", - "SSL_DH_anon_WITH_RC4_128_MD5", "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", - "TLS_RSA_WITH_NULL_SHA256", - "TLS_ECDHE_ECDSA_WITH_NULL_SHA", - "TLS_ECDHE_RSA_WITH_NULL_SHA", - "SSL_RSA_WITH_NULL_SHA", - "TLS_ECDH_ECDSA_WITH_NULL_SHA", - "TLS_ECDH_RSA_WITH_NULL_SHA", - "TLS_ECDH_anon_WITH_NULL_SHA", - "SSL_RSA_WITH_NULL_MD5", + "TLS_ECDH_anon_WITH_RC4_128_SHA", + "SSL_DH_anon_WITH_RC4_128_MD5", "SSL_RSA_WITH_DES_CBC_SHA", "SSL_DHE_RSA_WITH_DES_CBC_SHA", "SSL_DHE_DSS_WITH_DES_CBC_SHA", "SSL_DH_anon_WITH_DES_CBC_SHA", - "SSL_RSA_EXPORT_WITH_RC4_40_MD5", - "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", - "TLS_KRB5_WITH_RC4_128_SHA", - "TLS_KRB5_WITH_RC4_128_MD5", + "SSL_RSA_EXPORT_WITH_RC4_40_MD5", + "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", + "TLS_RSA_WITH_NULL_SHA256", + "TLS_ECDHE_ECDSA_WITH_NULL_SHA", + "TLS_ECDHE_RSA_WITH_NULL_SHA", + "SSL_RSA_WITH_NULL_SHA", + "TLS_ECDH_ECDSA_WITH_NULL_SHA", + "TLS_ECDH_RSA_WITH_NULL_SHA", + "TLS_ECDH_anon_WITH_NULL_SHA", + "SSL_RSA_WITH_NULL_MD5", "TLS_KRB5_WITH_3DES_EDE_CBC_SHA", "TLS_KRB5_WITH_3DES_EDE_CBC_MD5", + "TLS_KRB5_WITH_RC4_128_SHA", + "TLS_KRB5_WITH_RC4_128_MD5", "TLS_KRB5_WITH_DES_CBC_SHA", "TLS_KRB5_WITH_DES_CBC_MD5", - "TLS_KRB5_EXPORT_WITH_RC4_40_SHA", - "TLS_KRB5_EXPORT_WITH_RC4_40_MD5", "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", - "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5" + "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", + "TLS_KRB5_EXPORT_WITH_RC4_40_SHA", + "TLS_KRB5_EXPORT_WITH_RC4_40_MD5" ); private final static String[] protocols = {