8038913: Bolster XML support
authormullan
Wed, 11 Jun 2014 16:25:59 -0400
changeset 27081 1ceee8d3844d
parent 27080 4c4cdbcd69b5
child 27082 7ab1aa5e8713
8038913: Bolster XML support Reviewed-by: xuelei, skoivu
jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java
jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java
jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java
jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java
jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java
jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java
jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java
jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java
jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java
jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java
--- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java	Thu Jun 05 18:46:37 2014 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java	Wed Jun 11 16:25:59 2014 -0400
@@ -25,6 +25,8 @@
 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 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 @@
             log.log(java.util.logging.Level.FINE, "Registering default algorithms");
         }
         try {
-            //
-            // Bind the default prefixes
-            //
-            ElementProxy.registerDefaultPrefixes();
+            AccessController.doPrivileged(new PrivilegedExceptionAction<Void>(){
+                @Override public Void run() throws XMLSecurityException {
+                    //
+                    // Bind the default prefixes
+                    //
+                    ElementProxy.registerDefaultPrefixes();
 
-            //
-            // Set the default Transforms
-            //
-            Transform.registerDefaultAlgorithms();
+                    //
+                    // Set the default Transforms
+                    //
+                    Transform.registerDefaultAlgorithms();
 
-            //
-            // Set the default signature algorithms
-            //
-            SignatureAlgorithm.registerDefaultAlgorithms();
+                    //
+                    // Set the default signature algorithms
+                    //
+                    SignatureAlgorithm.registerDefaultAlgorithms();
+
+                    //
+                    // Set the default JCE algorithms
+                    //
+                    JCEMapper.registerDefaultAlgorithms();
 
-            //
-            // Set the default JCE algorithms
-            //
-            JCEMapper.registerDefaultAlgorithms();
+                    //
+                    // Set the default c14n algorithms
+                    //
+                    Canonicalizer.registerDefaultAlgorithms();
 
-            //
-            // Set the default c14n algorithms
-            //
-            Canonicalizer.registerDefaultAlgorithms();
+                    //
+                    // Register the default resolvers
+                    //
+                    ResourceResolver.registerDefaultResolvers();
 
-            //
-            // Register the default resolvers
-            //
-            ResourceResolver.registerDefaultResolvers();
+                    //
+                    // Register the default key resolvers
+                    //
+                    KeyResolver.registerDefaultResolvers();
 
-            //
-            // Register the default key resolvers
-            //
-            KeyResolver.registerDefaultResolvers();
-        } catch (Exception ex) {
-            log.log(java.util.logging.Level.SEVERE, ex.getMessage(), ex);
-            ex.printStackTrace();
+                    return null;
+                }
+           });
+        } catch (PrivilegedActionException ex) {
+            XMLSecurityException xse = (XMLSecurityException)ex.getException();
+            log.log(java.util.logging.Level.SEVERE, xse.getMessage(), xse);
+            xse.printStackTrace();
         }
     }
 
--- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java	Thu Jun 05 18:46:37 2014 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java	Wed Jun 11 16:25:59 2014 -0400
@@ -27,6 +27,7 @@
 
 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 @@
      *
      * @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);
     }
 
@@ -296,8 +300,11 @@
     /**
      * 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;
     }
 
--- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java	Thu Jun 05 18:46:37 2014 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java	Wed Jun 11 16:25:59 2014 -0400
@@ -37,6 +37,7 @@
 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 @@
     }
 
     /**
-     * Registers implementing class of the Transform algorithm with algorithmURI
+     * Registers implementing class of the SignatureAlgorithm with algorithmURI
      *
-     * @param algorithmURI algorithmURI URI representation of <code>Transform algorithm</code>.
+     * @param algorithmURI algorithmURI URI representation of <code>SignatureAlgorithm</code>.
      * @param implementingClass <code>implementingClass</code> 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 @@
     /**
      * Registers implementing class of the Transform algorithm with algorithmURI
      *
-     * @param algorithmURI algorithmURI URI representation of <code>Transform algorithm</code>.
+     * @param algorithmURI algorithmURI URI representation of <code>SignatureAlgorithm</code>.
      * @param implementingClass <code>implementingClass</code> 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<? extends SignatureAlgorithmSpi> 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);
         }
--- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java	Thu Jun 05 18:46:37 2014 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java	Wed Jun 11 16:25:59 2014 -0400
@@ -41,6 +41,7 @@
 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 @@
      * @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<? extends CanonicalizerSpi> registeredClass =
             canonicalizerHash.get(algorithmURI);
@@ -166,9 +170,12 @@
      * @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<CanonicalizerSpi> implementingClass)
+    public static void register(String algorithmURI, Class<? extends CanonicalizerSpi> implementingClass)
         throws AlgorithmAlreadyRegisteredException, ClassNotFoundException {
+        JavaUtils.checkRegisterPermission();
         // check whether URI is already registered
         Class<? extends CanonicalizerSpi> registeredClass = canonicalizerHash.get(algorithmURI);
 
--- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java	Thu Jun 05 18:46:37 2014 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java	Wed Jun 11 16:25:59 2014 -0400
@@ -42,6 +42,7 @@
 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 @@
      * @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 @@
      *
      * @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 @@
      *
      * @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 @@
      * @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<String> classNames)
         throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+        JavaUtils.checkRegisterPermission();
         List<KeyResolver> keyResolverList = new ArrayList<KeyResolver>(classNames.size());
         for (String className : classNames) {
             KeyResolverSpi keyResolverSpi =
--- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java	Thu Jun 05 18:46:37 2014 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java	Wed Jun 11 16:25:59 2014 -0400
@@ -46,6 +46,7 @@
 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 @@
      * 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<? extends TransformSpi> transformSpi = transformSpiHash.get(algorithmURI);
         if (transformSpi != null) {
@@ -206,9 +210,12 @@
      * 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<? extends TransformSpi> implementingClass)
         throws AlgorithmAlreadyRegisteredException {
+        JavaUtils.checkRegisterPermission();
         // are we already registered?
         Class<? extends TransformSpi> transformSpi = transformSpiHash.get(algorithmURI);
         if (transformSpi != null) {
--- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java	Thu Jun 05 18:46:37 2014 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java	Wed Jun 11 16:25:59 2014 -0400
@@ -468,9 +468,12 @@
      * @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)) {
--- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java	Thu Jun 05 18:46:37 2014 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java	Wed Jun 11 16:25:59 2014 -0400
@@ -28,6 +28,7 @@
 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 @@
     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
     }
@@ -147,6 +152,23 @@
     }
 
     /**
+     * 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);
+        }
+    }
+
+    /**
      * Converts an ASN.1 DSA value to a XML Signature DSA Value.
      *
      * The JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value
--- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java	Thu Jun 05 18:46:37 2014 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java	Wed Jun 11 16:25:59 2014 -0400
@@ -80,32 +80,44 @@
     /**
      * 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;
     }
 
--- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java	Thu Jun 05 18:46:37 2014 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java	Wed Jun 11 16:25:59 2014 -0400
@@ -27,6 +27,7 @@
 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 @@
      * 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<ResourceResolverSpi> resourceResolverClass =
                 (Class<ResourceResolverSpi>) Class.forName(className);
@@ -216,9 +220,12 @@
      * 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<ResourceResolverSpi> resourceResolverClass =
                 (Class<ResourceResolverSpi>) Class.forName(className);
@@ -233,8 +240,11 @@
      * 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<? extends ResourceResolverSpi> className, boolean start) {
+        JavaUtils.checkRegisterPermission();
         try {
             ResourceResolverSpi resourceResolverSpi = className.newInstance();
             register(resourceResolverSpi, start);
@@ -250,8 +260,11 @@
      * 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));