提交 eae7e7bf 编写于 作者: M mullan

6741606: Integrate Apache Santuario

Reviewed-by: vinnie, hawtin
上级 35d4f061
......@@ -2,38 +2,43 @@
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.sun.org.apache.xml.internal.security;
import java.io.InputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
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.keys.KeyInfo;
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;
import com.sun.org.apache.xml.internal.security.utils.I18n;
//import com.sun.org.apache.xml.internal.security.utils.PRNG;
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver;
import org.w3c.dom.Attr;
......@@ -47,367 +52,317 @@ import org.w3c.dom.Node;
* the mapping of Canonicalization and Transform algorithms. Initialization is
* done by calling {@link Init#init} which should be done in any static block
* of the files of this library. We ensure that this call is only executed once.
*
* @author $Author: mullan $
*/
public final class Init {
public class Init {
/** {@link java.util.logging} logging facility */
static java.util.logging.Logger log =
java.util.logging.Logger.getLogger(Init.class.getName());
/** The namespace for CONF file **/
public static final String CONF_NS = "http://www.xmlsecurity.org/NS/#configuration";
/** Field _initialized */
private static boolean _alreadyInitialized = false;
/** {@link org.apache.commons.logging} logging facility */
private static java.util.logging.Logger log =
java.util.logging.Logger.getLogger(Init.class.getName());
/** The namespace for CONF file **/
public static final String CONF_NS="http://www.xmlsecurity.org/NS/#configuration";
/** Field alreadyInitialized */
private static boolean alreadyInitialized = false;
/**
* Method isInitialized
* @return true if the librairy is already initialized.
*
* @return true if the library is already initialized.
*/
public static final boolean isInitialized() {
return Init._alreadyInitialized;
public static synchronized final boolean isInitialized() {
return Init.alreadyInitialized;
}
/**
* Method init
*
*/
public synchronized static void init() {
if (_alreadyInitialized) {
public static synchronized void init() {
if (alreadyInitialized) {
return;
}
long XX_configure_i18n_end=0;
long XX_configure_reg_c14n_start=0;
long XX_configure_reg_c14n_end=0;
long XX_configure_reg_jcemapper_end=0;
long XX_configure_reg_keyInfo_start=0;
long XX_configure_reg_keyResolver_end=0;
long XX_configure_reg_prefixes_start=0;
long XX_configure_reg_resourceresolver_start=0;
long XX_configure_reg_sigalgos_end=0;
long XX_configure_reg_transforms_end=0;
long XX_configure_reg_keyInfo_end=0;
long XX_configure_reg_keyResolver_start=0;
_alreadyInitialized = true;
try {
long XX_init_start = System.currentTimeMillis();
long XX_prng_start = System.currentTimeMillis();
InputStream is =
AccessController.doPrivileged(
new PrivilegedAction<InputStream>() {
public InputStream run() {
String cfile =
System.getProperty("com.sun.org.apache.xml.internal.security.resource.config");
if (cfile == null) {
return null;
}
return getClass().getResourceAsStream(cfile);
}
});
if (is == null) {
dynamicInit();
} else {
fileInit(is);
}
//PRNG.init(new java.security.SecureRandom());
alreadyInitialized = true;
}
long XX_prng_end = System.currentTimeMillis();
/**
* Dynamically initialise the library by registering the default algorithms/implementations
*/
private static void dynamicInit() {
//
// Load the Resource Bundle - the default is the English resource bundle.
// To load another resource bundle, call I18n.init(...) before calling this
// method.
//
I18n.init("en", "US");
if (log.isLoggable(java.util.logging.Level.FINE)) {
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();
}
}
/**
* Initialise the library from a configuration file
*/
private static void fileInit(InputStream is) {
try {
/* read library configuration file */
long XX_parsing_start = System.currentTimeMillis();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
dbf.setNamespaceAware(true);
dbf.setValidating(false);
DocumentBuilder db = dbf.newDocumentBuilder();
// We don't allow users to override the Apache XML Security
// configuration in the JRE. Users should use the standard security
// provider mechanism instead if implementing their own
// transform or canonicalization algorithms.
// InputStream is = Class.forName("com.sun.org.apache.xml.internal.security.Init").getResourceAsStream("resource/config.xml");
InputStream is = AccessController.doPrivileged(
new PrivilegedAction<InputStream>() {
public InputStream run() {
// String cfile = System.getProperty
// ("com.sun.org.apache.xml.internal.security.resource.config");
return getClass().getResourceAsStream
// (cfile != null ? cfile : "resource/config.xml");
("resource/config.xml");
}
});
Document doc = db.parse(is);
long XX_parsing_end = System.currentTimeMillis();
long XX_configure_i18n_start = 0;
{
XX_configure_reg_keyInfo_start = System.currentTimeMillis();
try {
KeyInfo.init();
} catch (Exception e) {
e.printStackTrace();
throw e;
}
XX_configure_reg_keyInfo_end = System.currentTimeMillis();
}
long XX_configure_reg_transforms_start=0;
long XX_configure_reg_jcemapper_start=0;
long XX_configure_reg_sigalgos_start=0;
long XX_configure_reg_resourceresolver_end=0;
long XX_configure_reg_prefixes_end=0;
Node config=doc.getFirstChild();
for (;config!=null;config=config.getNextSibling()) {
Node config = doc.getFirstChild();
for (; config != null; config = config.getNextSibling()) {
if ("Configuration".equals(config.getLocalName())) {
break;
}
}
for (Node el=config.getFirstChild();el!=null;el=el.getNextSibling()) {
if (el.getNodeType() != Node.ELEMENT_NODE) {
if (config == null) {
log.log(java.util.logging.Level.SEVERE, "Error in reading configuration file - Configuration element not found");
return;
}
for (Node el = config.getFirstChild(); el != null; el = el.getNextSibling()) {
if (Node.ELEMENT_NODE != el.getNodeType()) {
continue;
}
String tag=el.getLocalName();
//
// Commented out: not supported in the JDK. We use the default locale.
//
// if (tag.equals("ResourceBundles")){
// XX_configure_i18n_start = System.currentTimeMillis();
// Element resource=(Element)el;
// /* configure internationalization */
// Attr langAttr = resource.getAttributeNode("defaultLanguageCode");
// Attr countryAttr = resource.getAttributeNode("defaultCountryCode");
// String languageCode = (langAttr == null)
// ? null
// : langAttr.getNodeValue();
// String countryCode = (countryAttr == null)
// ? null
// : countryAttr.getNodeValue();
//
// I18n.init(languageCode, countryCode);
// XX_configure_i18n_end = System.currentTimeMillis();
// }
if (tag.equals("CanonicalizationMethods")){
XX_configure_reg_c14n_start = System.currentTimeMillis();
Canonicalizer.init();
Element[] list=XMLUtils.selectNodes(el.getFirstChild(),CONF_NS,"CanonicalizationMethod");
String tag = el.getLocalName();
if (tag.equals("ResourceBundles")) {
Element resource = (Element)el;
/* configure internationalization */
Attr langAttr = resource.getAttributeNode("defaultLanguageCode");
Attr countryAttr = resource.getAttributeNode("defaultCountryCode");
String languageCode =
(langAttr == null) ? null : langAttr.getNodeValue();
String countryCode =
(countryAttr == null) ? null : countryAttr.getNodeValue();
I18n.init(languageCode, countryCode);
}
if (tag.equals("CanonicalizationMethods")) {
Element[] list =
XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "CanonicalizationMethod");
for (int i = 0; i < list.length; i++) {
String URI = list[i].getAttributeNS(null,
"URI");
String JAVACLASS =
list[i].getAttributeNS(null,
"JAVACLASS");
String uri = list[i].getAttributeNS(null, "URI");
String javaClass =
list[i].getAttributeNS(null, "JAVACLASS");
try {
Class.forName(JAVACLASS);
/* Method methods[] = c.getMethods();
for (int j = 0; j < methods.length; j++) {
Method currMeth = methods[j];
if (currMeth.getDeclaringClass().getName()
.equals(JAVACLASS)) {
log.log(java.util.logging.Level.FINE, currMeth.getDe claringClass().toString());
Canonicalizer.register(uri, javaClass);
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Canonicalizer.register(" + uri + ", " + javaClass + ")");
}
}*/
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "Canonicalizer.register(" + URI + ", "
+ JAVACLASS + ")");
Canonicalizer.register(URI, JAVACLASS);
} catch (ClassNotFoundException e) {
Object exArgs[] = { URI, JAVACLASS };
log.log(java.util.logging.Level.SEVERE, I18n.translate("algorithm.classDoesNotExist",
exArgs));
Object exArgs[] = { uri, javaClass };
log.log(java.util.logging.Level.SEVERE, I18n.translate("algorithm.classDoesNotExist", exArgs));
}
}
XX_configure_reg_c14n_end = System.currentTimeMillis();
}
if (tag.equals("TransformAlgorithms")){
XX_configure_reg_transforms_start = System.currentTimeMillis();
Transform.init();
Element[] tranElem = XMLUtils.selectNodes(el.getFirstChild(),CONF_NS,"TransformAlgorithm");
if (tag.equals("TransformAlgorithms")) {
Element[] tranElem =
XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "TransformAlgorithm");
for (int i = 0; i < tranElem.length; i++) {
String URI = tranElem[i].getAttributeNS(null,
"URI");
String JAVACLASS =
tranElem[i].getAttributeNS(null,
"JAVACLASS");
String uri = tranElem[i].getAttributeNS(null, "URI");
String javaClass =
tranElem[i].getAttributeNS(null, "JAVACLASS");
try {
Class.forName(JAVACLASS);
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "Transform.register(" + URI + ", " + JAVACLASS + ")");
Transform.register(URI, JAVACLASS);
Transform.register(uri, javaClass);
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Transform.register(" + uri + ", " + javaClass + ")");
}
} catch (ClassNotFoundException e) {
Object exArgs[] = { URI, JAVACLASS };
log.log(java.util.logging.Level.SEVERE, I18n.translate("algorithm.classDoesNotExist",
exArgs));
Object exArgs[] = { uri, javaClass };
log.log(java.util.logging.Level.SEVERE, I18n.translate("algorithm.classDoesNotExist", exArgs));
} catch (NoClassDefFoundError ex) {
log.log(java.util.logging.Level.WARNING, "Not able to found dependecies for algorithm, I'm keep working.");
log.log(java.util.logging.Level.WARNING, "Not able to found dependencies for algorithm, I'll keep working.");
}
}
XX_configure_reg_transforms_end = System.currentTimeMillis();
}
if ("JCEAlgorithmMappings".equals(tag)){
XX_configure_reg_jcemapper_start = System.currentTimeMillis();
JCEMapper.init((Element)el);
XX_configure_reg_jcemapper_end = System.currentTimeMillis();
if ("JCEAlgorithmMappings".equals(tag)) {
Node algorithmsNode = ((Element)el).getElementsByTagName("Algorithms").item(0);
if (algorithmsNode != null) {
Element[] algorithms =
XMLUtils.selectNodes(algorithmsNode.getFirstChild(), CONF_NS, "Algorithm");
for (int i = 0; i < algorithms.length; i++) {
Element element = algorithms[i];
String id = element.getAttribute("URI");
JCEMapper.register(id, new JCEMapper.Algorithm(element));
}
}
}
if (tag.equals("SignatureAlgorithms")){
XX_configure_reg_sigalgos_start = System.currentTimeMillis();
SignatureAlgorithm.providerInit();
Element[] sigElems = XMLUtils.selectNodes(el.getFirstChild(), CONF_NS,
"SignatureAlgorithm");
if (tag.equals("SignatureAlgorithms")) {
Element[] sigElems =
XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "SignatureAlgorithm");
for (int i = 0; i < sigElems.length; i++) {
String URI = sigElems[i].getAttributeNS(null,
"URI");
String JAVACLASS =
sigElems[i].getAttributeNS(null,
"JAVACLASS");
String uri = sigElems[i].getAttributeNS(null, "URI");
String javaClass =
sigElems[i].getAttributeNS(null, "JAVACLASS");
/** $todo$ handle registering */
try {
Class.forName(JAVACLASS);
// Method methods[] = c.getMethods();
// for (int j = 0; j < methods.length; j++) {
// Method currMeth = methods[j];
//
// if (currMeth.getDeclaringClass().getName()
// .equals(JAVACLASS)) {
// log.log(java.util.logging.Level.FINE, currMeth.getDe claringClass().toString());
// }
// }
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "SignatureAlgorithm.register(" + URI + ", " + JAVACLASS + ")");
SignatureAlgorithm.register(URI, JAVACLASS);
SignatureAlgorithm.register(uri, javaClass);
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "SignatureAlgorithm.register(" + uri + ", "
+ javaClass + ")");
}
} catch (ClassNotFoundException e) {
Object exArgs[] = { URI, JAVACLASS };
log.log(java.util.logging.Level.SEVERE, I18n.translate("algorithm.classDoesNotExist",
exArgs));
Object exArgs[] = { uri, javaClass };
log.log(java.util.logging.Level.SEVERE, I18n.translate("algorithm.classDoesNotExist", exArgs));
}
}
XX_configure_reg_sigalgos_end = System.currentTimeMillis();
}
if (tag.equals("ResourceResolvers")){
XX_configure_reg_resourceresolver_start = System.currentTimeMillis();
ResourceResolver.init();
Element[]resolverElem = XMLUtils.selectNodes(el.getFirstChild(),CONF_NS,
"Resolver");
if (tag.equals("ResourceResolvers")) {
Element[]resolverElem =
XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "Resolver");
for (int i = 0; i < resolverElem.length; i++) {
String JAVACLASS =
resolverElem[i].getAttributeNS(null,
"JAVACLASS");
String Description =
resolverElem[i].getAttributeNS(null,
"DESCRIPTION");
if ((Description != null) && (Description.length() > 0)) {
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "Register Resolver: " + JAVACLASS + ": " + Description);
String javaClass =
resolverElem[i].getAttributeNS(null, "JAVACLASS");
String description =
resolverElem[i].getAttributeNS(null, "DESCRIPTION");
if ((description != null) && (description.length() > 0)) {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Register Resolver: " + javaClass + ": "
+ description);
}
} else {
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "Register Resolver: " + JAVACLASS + ": For unknown purposes");
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Register Resolver: " + javaClass
+ ": For unknown purposes");
}
}
try {
ResourceResolver.register(JAVACLASS);
ResourceResolver.register(javaClass);
} catch (Throwable e) {
log.log(java.util.logging.Level.WARNING, "Cannot register:"+JAVACLASS+" perhaps some needed jars are not installed",e);
log.log(java.util.logging.Level.WARNING,
"Cannot register:" + javaClass
+ " perhaps some needed jars are not installed",
e
);
}
XX_configure_reg_resourceresolver_end =
System.currentTimeMillis();
}
}
if (tag.equals("KeyResolver")){
XX_configure_reg_keyResolver_start =System.currentTimeMillis();
KeyResolver.init();
Element[] resolverElem = XMLUtils.selectNodes(el.getFirstChild(), CONF_NS,"Resolver");
Element[] resolverElem =
XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "Resolver");
List<String> classNames = new ArrayList<String>(resolverElem.length);
for (int i = 0; i < resolverElem.length; i++) {
String JAVACLASS =
resolverElem[i].getAttributeNS(null,
"JAVACLASS");
String Description =
resolverElem[i].getAttributeNS(null,
"DESCRIPTION");
if ((Description != null) && (Description.length() > 0)) {
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "Register Resolver: " + JAVACLASS + ": " + Description);
String javaClass =
resolverElem[i].getAttributeNS(null, "JAVACLASS");
String description =
resolverElem[i].getAttributeNS(null, "DESCRIPTION");
if ((description != null) && (description.length() > 0)) {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Register Resolver: " + javaClass + ": "
+ description);
}
} else {
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "Register Resolver: " + JAVACLASS + ": For unknown purposes");
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Register Resolver: " + javaClass
+ ": For unknown purposes");
}
KeyResolver.register(JAVACLASS);
}
XX_configure_reg_keyResolver_end = System.currentTimeMillis();
classNames.add(javaClass);
}
KeyResolver.registerClassNames(classNames);
}
if (tag.equals("PrefixMappings")){
XX_configure_reg_prefixes_start = System.currentTimeMillis();
if (log.isLoggable(java.util.logging.Level.FINE))
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Now I try to bind prefixes:");
}
Element[] nl = XMLUtils.selectNodes(el.getFirstChild(), CONF_NS,"PrefixMapping");
Element[] nl =
XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "PrefixMapping");
for (int i = 0; i < nl.length; i++) {
String namespace = nl[i].getAttributeNS(null,
"namespace");
String prefix = nl[i].getAttributeNS(null,
"prefix");
if (log.isLoggable(java.util.logging.Level.FINE))
String namespace = nl[i].getAttributeNS(null, "namespace");
String prefix = nl[i].getAttributeNS(null, "prefix");
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Now I try to bind " + prefix + " to " + namespace);
com.sun.org.apache.xml.internal.security.utils.ElementProxy
.setDefaultPrefix(namespace, prefix);
}
XX_configure_reg_prefixes_end = System.currentTimeMillis();
ElementProxy.setDefaultPrefix(namespace, prefix);
}
}
long XX_init_end = System.currentTimeMillis();
//J-
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "XX_init " + ((int)(XX_init_end - XX_init_start)) + " ms");
log.log(java.util.logging.Level.FINE, " XX_prng " + ((int)(XX_prng_end - XX_prng_start)) + " ms");
log.log(java.util.logging.Level.FINE, " XX_parsing " + ((int)(XX_parsing_end - XX_parsing_start)) + " ms");
log.log(java.util.logging.Level.FINE, " XX_configure_i18n " + ((int)(XX_configure_i18n_end- XX_configure_i18n_start)) + " ms");
log.log(java.util.logging.Level.FINE, " XX_configure_reg_c14n " + ((int)(XX_configure_reg_c14n_end- XX_configure_reg_c14n_start)) + " ms");
log.log(java.util.logging.Level.FINE, " XX_configure_reg_jcemapper " + ((int)(XX_configure_reg_jcemapper_end- XX_configure_reg_jcemapper_start)) + " ms");
log.log(java.util.logging.Level.FINE, " XX_configure_reg_keyInfo " + ((int)(XX_configure_reg_keyInfo_end- XX_configure_reg_keyInfo_start)) + " ms");
log.log(java.util.logging.Level.FINE, " XX_configure_reg_keyResolver " + ((int)(XX_configure_reg_keyResolver_end- XX_configure_reg_keyResolver_start)) + " ms");
log.log(java.util.logging.Level.FINE, " XX_configure_reg_prefixes " + ((int)(XX_configure_reg_prefixes_end- XX_configure_reg_prefixes_start)) + " ms");
log.log(java.util.logging.Level.FINE, " XX_configure_reg_resourceresolver " + ((int)(XX_configure_reg_resourceresolver_end- XX_configure_reg_resourceresolver_start)) + " ms");
log.log(java.util.logging.Level.FINE, " XX_configure_reg_sigalgos " + ((int)(XX_configure_reg_sigalgos_end- XX_configure_reg_sigalgos_start)) + " ms");
log.log(java.util.logging.Level.FINE, " XX_configure_reg_transforms " + ((int)(XX_configure_reg_transforms_end- XX_configure_reg_transforms_start)) + " ms");
}
} catch (Exception e) {
log.log(java.util.logging.Level.SEVERE, "Bad: ", e);
e.printStackTrace();
}
}
}
......@@ -2,134 +2,255 @@
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.sun.org.apache.xml.internal.security.algorithms;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.sun.org.apache.xml.internal.security.Init;
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import com.sun.org.apache.xml.internal.security.encryption.XMLCipher;
import com.sun.org.apache.xml.internal.security.signature.XMLSignature;
import org.w3c.dom.Element;
/**
* This class maps algorithm identifier URIs to JAVA JCE class names.
*
* @author $Author: mullan $
*/
public class JCEMapper {
/** {@link java.util.logging} logging facility */
static java.util.logging.Logger log =
/** {@link org.apache.commons.logging} logging facility */
private static java.util.logging.Logger log =
java.util.logging.Logger.getLogger(JCEMapper.class.getName());
private static Map<String, String> uriToJCEName;
private static Map<String, Algorithm> algorithmsMap;
private static Map<String, Algorithm> algorithmsMap =
new ConcurrentHashMap<String, Algorithm>();
private static String providerName = null;
/**
* Method init
* Method register
*
* @param mappingElement
* @throws Exception
* @param id
* @param algorithm
*/
public static void init(Element mappingElement) throws Exception {
loadAlgorithms((Element)mappingElement.getElementsByTagName("Algorithms").item(0));
}
static void loadAlgorithms( Element algorithmsEl) {
Element[] algorithms = XMLUtils.selectNodes(algorithmsEl.getFirstChild(),Init.CONF_NS,"Algorithm");
uriToJCEName = new HashMap<String, String>( algorithms.length * 2);
algorithmsMap = new HashMap<String, Algorithm>( algorithms.length * 2);
for (int i = 0 ;i < algorithms.length ;i ++) {
Element el = algorithms[i];
String id = el.getAttribute("URI");
String jceName = el.getAttribute("JCEName");
uriToJCEName.put(id, jceName);
algorithmsMap.put(id, new Algorithm(el));
}
public static void register(String id, Algorithm algorithm) {
algorithmsMap.put(id, algorithm);
}
static Algorithm getAlgorithmMapping(String algoURI) {
return algorithmsMap.get(algoURI);
/**
* This method registers the default algorithms.
*/
public static void registerDefaultAlgorithms() {
algorithmsMap.put(
MessageDigestAlgorithm.ALGO_ID_DIGEST_NOT_RECOMMENDED_MD5,
new Algorithm("", "MD5", "MessageDigest")
);
algorithmsMap.put(
MessageDigestAlgorithm.ALGO_ID_DIGEST_RIPEMD160,
new Algorithm("", "RIPEMD160", "MessageDigest")
);
algorithmsMap.put(
MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA1,
new Algorithm("", "SHA-1", "MessageDigest")
);
algorithmsMap.put(
MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA256,
new Algorithm("", "SHA-256", "MessageDigest")
);
algorithmsMap.put(
MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA384,
new Algorithm("", "SHA-384", "MessageDigest")
);
algorithmsMap.put(
MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA512,
new Algorithm("", "SHA-512", "MessageDigest")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_SIGNATURE_DSA,
new Algorithm("", "SHA1withDSA", "Signature")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5,
new Algorithm("", "MD5withRSA", "Signature")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_SIGNATURE_RSA_RIPEMD160,
new Algorithm("", "RIPEMD160withRSA", "Signature")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1,
new Algorithm("", "SHA1withRSA", "Signature")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256,
new Algorithm("", "SHA256withRSA", "Signature")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384,
new Algorithm("", "SHA384withRSA", "Signature")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512,
new Algorithm("", "SHA512withRSA", "Signature")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA1,
new Algorithm("", "SHA1withECDSA", "Signature")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5,
new Algorithm("", "HmacMD5", "Mac")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_MAC_HMAC_RIPEMD160,
new Algorithm("", "HMACRIPEMD160", "Mac")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_MAC_HMAC_SHA1,
new Algorithm("", "HmacSHA1", "Mac")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_MAC_HMAC_SHA256,
new Algorithm("", "HmacSHA256", "Mac")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_MAC_HMAC_SHA384,
new Algorithm("", "HmacSHA384", "Mac")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_MAC_HMAC_SHA512,
new Algorithm("", "HmacSHA512", "Mac")
);
algorithmsMap.put(
XMLCipher.TRIPLEDES,
new Algorithm("DESede", "DESede/CBC/ISO10126Padding", "BlockEncryption", 192)
);
algorithmsMap.put(
XMLCipher.AES_128,
new Algorithm("AES", "AES/CBC/ISO10126Padding", "BlockEncryption", 128)
);
algorithmsMap.put(
XMLCipher.AES_192,
new Algorithm("AES", "AES/CBC/ISO10126Padding", "BlockEncryption", 192)
);
algorithmsMap.put(
XMLCipher.AES_256,
new Algorithm("AES", "AES/CBC/ISO10126Padding", "BlockEncryption", 256)
);
algorithmsMap.put(
XMLCipher.RSA_v1dot5,
new Algorithm("RSA", "RSA/ECB/PKCS1Padding", "KeyTransport")
);
algorithmsMap.put(
XMLCipher.RSA_OAEP,
new Algorithm("RSA", "RSA/ECB/OAEPPadding", "KeyTransport")
);
algorithmsMap.put(
XMLCipher.DIFFIE_HELLMAN,
new Algorithm("", "", "KeyAgreement")
);
algorithmsMap.put(
XMLCipher.TRIPLEDES_KeyWrap,
new Algorithm("DESede", "DESedeWrap", "SymmetricKeyWrap", 192)
);
algorithmsMap.put(
XMLCipher.AES_128_KeyWrap,
new Algorithm("AES", "AESWrap", "SymmetricKeyWrap", 128)
);
algorithmsMap.put(
XMLCipher.AES_192_KeyWrap,
new Algorithm("AES", "AESWrap", "SymmetricKeyWrap", 192)
);
algorithmsMap.put(
XMLCipher.AES_256_KeyWrap,
new Algorithm("AES", "AESWrap", "SymmetricKeyWrap", 256)
);
}
/**
* Method translateURItoJCEID
*
* @param AlgorithmURI
* @param algorithmURI
* @return the JCE standard name corresponding to the given URI
*
*/
public static String translateURItoJCEID(String AlgorithmURI) {
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "Request for URI " + AlgorithmURI);
public static String translateURItoJCEID(String algorithmURI) {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Request for URI " + algorithmURI);
}
String jceName = uriToJCEName.get(AlgorithmURI);
return jceName;
Algorithm algorithm = algorithmsMap.get(algorithmURI);
if (algorithm != null) {
return algorithm.jceName;
}
return null;
}
/**
* Method getAlgorithmClassFromURI
* NOTE(Raul Benito) It seems a buggy function the loop doesn't do
* anything??
* @param AlgorithmURI
* @param algorithmURI
* @return the class name that implements this algorithm
*
*/
public static String getAlgorithmClassFromURI(String AlgorithmURI) {
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "Request for URI " + AlgorithmURI);
public static String getAlgorithmClassFromURI(String algorithmURI) {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Request for URI " + algorithmURI);
}
return (algorithmsMap.get(AlgorithmURI)).algorithmClass;
Algorithm algorithm = algorithmsMap.get(algorithmURI);
if (algorithm != null) {
return algorithm.algorithmClass;
}
return null;
}
/**
* Returns the keylength in bit for a particular algorithm.
* Returns the keylength in bits for a particular algorithm.
*
* @param AlgorithmURI
* @return The length of the key used in the alogrithm
* @param algorithmURI
* @return The length of the key used in the algorithm
*/
public static int getKeyLengthFromURI(String AlgorithmURI) {
return Integer.parseInt((algorithmsMap.get(AlgorithmURI)).keyLength);
public static int getKeyLengthFromURI(String algorithmURI) {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Request for URI " + algorithmURI);
}
Algorithm algorithm = algorithmsMap.get(algorithmURI);
if (algorithm != null) {
return algorithm.keyLength;
}
return 0;
}
/**
* Method getJCEKeyAlgorithmFromURI
*
* @param AlgorithmURI
* @param algorithmURI
* @return The KeyAlgorithm for the given URI.
*
*/
public static String getJCEKeyAlgorithmFromURI(String AlgorithmURI) {
return (algorithmsMap.get(AlgorithmURI)).requiredKey;
public static String getJCEKeyAlgorithmFromURI(String algorithmURI) {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Request for URI " + algorithmURI);
}
Algorithm algorithm = algorithmsMap.get(algorithmURI);
if (algorithm != null) {
return algorithm.requiredKey;
}
return null;
}
/**
......@@ -145,24 +266,52 @@ public class JCEMapper {
* @param provider the default providerId.
*/
public static void setProviderId(String provider) {
providerName=provider;
providerName = provider;
}
/**
* Represents the Algorithm xml element
*/
public static class Algorithm {
String algorithmClass;
String keyLength;
String requiredKey;
final String requiredKey;
final String jceName;
final String algorithmClass;
final int keyLength;
/**
* Gets data from element
* @param el
*/
public Algorithm(Element el) {
algorithmClass=el.getAttribute("AlgorithmClass");
keyLength=el.getAttribute("KeyLength");
requiredKey=el.getAttribute("RequiredKey");
requiredKey = el.getAttribute("RequiredKey");
jceName = el.getAttribute("JCEName");
algorithmClass = el.getAttribute("AlgorithmClass");
if (el.hasAttribute("KeyLength")) {
keyLength = Integer.parseInt(el.getAttribute("KeyLength"));
} else {
keyLength = 0;
}
}
public Algorithm(String requiredKey, String jceName) {
this(requiredKey, jceName, null, 0);
}
public Algorithm(String requiredKey, String jceName, String algorithmClass) {
this(requiredKey, jceName, algorithmClass, 0);
}
public Algorithm(String requiredKey, String jceName, int keyLength) {
this(requiredKey, jceName, null, keyLength);
}
public Algorithm(String requiredKey, String jceName, String algorithmClass, int keyLength) {
this.requiredKey = requiredKey;
this.jceName = jceName;
this.algorithmClass = algorithmClass;
this.keyLength = keyLength;
}
}
}
......@@ -2,85 +2,66 @@
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.sun.org.apache.xml.internal.security.algorithms;
import java.security.Key;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac;
import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA;
import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureDSA;
import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureECDSA;
import com.sun.org.apache.xml.internal.security.exceptions.AlgorithmAlreadyRegisteredException;
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.ClassLoaderUtils;
import com.sun.org.apache.xml.internal.security.utils.Constants;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* Allows selection of digital signature's algorithm, private keys, other security parameters, and algorithm's ID.
* Allows selection of digital signature's algorithm, private keys, other
* security parameters, and algorithm's ID.
*
* @author Christian Geuer-Pollmann
*/
public class SignatureAlgorithm extends Algorithm {
/** {@link java.util.logging} logging facility */
static java.util.logging.Logger log =
/** {@link org.apache.commons.logging} logging facility */
private static java.util.logging.Logger log =
java.util.logging.Logger.getLogger(SignatureAlgorithm.class.getName());
/** Field _alreadyInitialized */
static boolean _alreadyInitialized = false;
/** All available algorithm classes are registered here */
static Map<String, Class<? extends SignatureAlgorithmSpi>> _algorithmHash = null;
static ThreadLocal<Map<String, SignatureAlgorithmSpi>> instancesSigning=new ThreadLocal<Map<String, SignatureAlgorithmSpi>>() {
protected Map<String, SignatureAlgorithmSpi> initialValue() {
return new HashMap<String, SignatureAlgorithmSpi>();
};
};
static ThreadLocal<Map<String, SignatureAlgorithmSpi>> instancesVerify=new ThreadLocal<Map<String, SignatureAlgorithmSpi>>() {
protected Map<String, SignatureAlgorithmSpi> initialValue() {
return new HashMap<String, SignatureAlgorithmSpi>();
};
};
static ThreadLocal<Map<String, Key>> keysSigning=new ThreadLocal<Map<String, Key>>() {
protected Map<String, Key> initialValue() {
return new HashMap<String, Key>();
};
};
static ThreadLocal<Map<String, Key>> keysVerify=new ThreadLocal<Map<String, Key>>() {
protected Map<String, Key> initialValue() {
return new HashMap<String, Key>();
};
};
// boolean isForSigning=false;
/** Field _signatureAlgorithm */
protected SignatureAlgorithmSpi _signatureAlgorithm = null;
private String algorithmURI;
private static Map<String, Class<? extends SignatureAlgorithmSpi>> algorithmHash =
new ConcurrentHashMap<String, Class<? extends SignatureAlgorithmSpi>>();
/** Field signatureAlgorithm */
private final SignatureAlgorithmSpi signatureAlgorithm;
private final String algorithmURI;
/**
* Constructor SignatureAlgorithm
......@@ -89,103 +70,102 @@ public class SignatureAlgorithm extends Algorithm {
* @param algorithmURI
* @throws XMLSecurityException
*/
public SignatureAlgorithm(Document doc, String algorithmURI)
throws XMLSecurityException {
public SignatureAlgorithm(Document doc, String algorithmURI) throws XMLSecurityException {
super(doc, algorithmURI);
this.algorithmURI = algorithmURI;
}
private void initializeAlgorithm(boolean isForSigning) throws XMLSignatureException {
if (_signatureAlgorithm!=null) {
return;
}
_signatureAlgorithm=isForSigning ? getInstanceForSigning(algorithmURI) : getInstanceForVerify(algorithmURI);
this._signatureAlgorithm
.engineGetContextFromElement(this._constructionElement);
}
private static SignatureAlgorithmSpi getInstanceForSigning(String algorithmURI) throws XMLSignatureException {
SignatureAlgorithmSpi result= instancesSigning.get().get(algorithmURI);
if (result!=null) {
result.reset();
return result;
}
result=buildSigner(algorithmURI, result);
instancesSigning.get().put(algorithmURI,result);
return result;
signatureAlgorithm = getSignatureAlgorithmSpi(algorithmURI);
signatureAlgorithm.engineGetContextFromElement(this._constructionElement);
}
private static SignatureAlgorithmSpi getInstanceForVerify(String algorithmURI) throws XMLSignatureException {
SignatureAlgorithmSpi result= instancesVerify.get().get(algorithmURI);
if (result!=null) {
result.reset();
return result;
}
result=buildSigner(algorithmURI, result);
instancesVerify.get().put(algorithmURI,result);
return result;
}
private static SignatureAlgorithmSpi buildSigner(String algorithmURI, SignatureAlgorithmSpi result) throws XMLSignatureException {
try {
Class<? extends SignatureAlgorithmSpi> implementingClass =
SignatureAlgorithm.getImplementingClass(algorithmURI);
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "Create URI \"" + algorithmURI + "\" class \""
+ implementingClass + "\"");
result= implementingClass.newInstance();
return result;
} catch (IllegalAccessException ex) {
Object exArgs[] = { algorithmURI, ex.getMessage() };
throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs,
ex);
} catch (InstantiationException ex) {
Object exArgs[] = { algorithmURI, ex.getMessage() };
throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs,
ex);
} catch (NullPointerException ex) {
Object exArgs[] = { algorithmURI, ex.getMessage() };
throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs,
ex);
}
}
/**
* Constructor SignatureAlgorithm
*
* @param doc
* @param algorithmURI
* @param HMACOutputLength
* @param hmacOutputLength
* @throws XMLSecurityException
*/
public SignatureAlgorithm(
Document doc, String algorithmURI, int HMACOutputLength)
throws XMLSecurityException {
Document doc, String algorithmURI, int hmacOutputLength
) throws XMLSecurityException {
super(doc, algorithmURI);
this.algorithmURI = algorithmURI;
signatureAlgorithm = getSignatureAlgorithmSpi(algorithmURI);
signatureAlgorithm.engineGetContextFromElement(this._constructionElement);
this(doc, algorithmURI);
this.algorithmURI=algorithmURI;
initializeAlgorithm(true);
this._signatureAlgorithm.engineSetHMACOutputLength(HMACOutputLength);
((IntegrityHmac)this._signatureAlgorithm)
.engineAddContextToElement(this._constructionElement);
signatureAlgorithm.engineSetHMACOutputLength(hmacOutputLength);
((IntegrityHmac)signatureAlgorithm).engineAddContextToElement(_constructionElement);
}
/**
* Constructor SignatureAlgorithm
*
* @param element
* @param BaseURI
* @param baseURI
* @throws XMLSecurityException
*/
public SignatureAlgorithm(Element element, String BaseURI)
throws XMLSecurityException {
public SignatureAlgorithm(Element element, String baseURI) throws XMLSecurityException {
this(element, baseURI, false);
}
super(element, BaseURI);
/**
* Constructor SignatureAlgorithm
*
* @param element
* @param baseURI
* @param secureValidation
* @throws XMLSecurityException
*/
public SignatureAlgorithm(
Element element, String baseURI, boolean secureValidation
) throws XMLSecurityException {
super(element, baseURI);
algorithmURI = this.getURI();
Attr attr = element.getAttributeNodeNS(null, "Id");
if (attr != null) {
element.setIdAttributeNode(attr, true);
}
if (secureValidation && (XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5.equals(algorithmURI)
|| XMLSignature.ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5.equals(algorithmURI))) {
Object exArgs[] = { algorithmURI };
throw new XMLSecurityException("signature.signatureAlgorithm", exArgs);
}
signatureAlgorithm = getSignatureAlgorithmSpi(algorithmURI);
signatureAlgorithm.engineGetContextFromElement(this._constructionElement);
}
/**
* Get a SignatureAlgorithmSpi object corresponding to the algorithmURI argument
*/
private static SignatureAlgorithmSpi getSignatureAlgorithmSpi(String algorithmURI)
throws XMLSignatureException {
try {
Class<? extends SignatureAlgorithmSpi> implementingClass =
algorithmHash.get(algorithmURI);
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Create URI \"" + algorithmURI + "\" class \""
+ implementingClass + "\"");
}
return implementingClass.newInstance();
} catch (IllegalAccessException ex) {
Object exArgs[] = { algorithmURI, ex.getMessage() };
throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs, ex);
} catch (InstantiationException ex) {
Object exArgs[] = { algorithmURI, ex.getMessage() };
throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs, ex);
} catch (NullPointerException ex) {
Object exArgs[] = { algorithmURI, ex.getMessage() };
throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs, ex);
}
}
/**
* Proxy method for {@link java.security.Signature#sign()}
* which is executed on the internal {@link java.security.Signature} object.
......@@ -194,7 +174,7 @@ public class SignatureAlgorithm extends Algorithm {
* @throws XMLSignatureException
*/
public byte[] sign() throws XMLSignatureException {
return this._signatureAlgorithm.engineSign();
return signatureAlgorithm.engineSign();
}
/**
......@@ -204,25 +184,16 @@ public class SignatureAlgorithm extends Algorithm {
* @return the result of the {@link java.security.Signature#getAlgorithm} method
*/
public String getJCEAlgorithmString() {
try {
return getInstanceForVerify(algorithmURI).engineGetJCEAlgorithmString();
} catch (XMLSignatureException e) {
//Ignore.
return null;
}
return signatureAlgorithm.engineGetJCEAlgorithmString();
}
/**
* Method getJCEProviderName
*
* @return The Provider of this Signature Alogrithm
* @return The Provider of this Signature Algorithm
*/
public String getJCEProviderName() {
try {
return getInstanceForVerify(algorithmURI).engineGetJCEProviderName();
} catch (XMLSignatureException e) {
return null;
}
return signatureAlgorithm.engineGetJCEProviderName();
}
/**
......@@ -233,7 +204,7 @@ public class SignatureAlgorithm extends Algorithm {
* @throws XMLSignatureException
*/
public void update(byte[] input) throws XMLSignatureException {
this._signatureAlgorithm.engineUpdate(input);
signatureAlgorithm.engineUpdate(input);
}
/**
......@@ -244,7 +215,7 @@ public class SignatureAlgorithm extends Algorithm {
* @throws XMLSignatureException
*/
public void update(byte input) throws XMLSignatureException {
this._signatureAlgorithm.engineUpdate(input);
signatureAlgorithm.engineUpdate(input);
}
/**
......@@ -256,9 +227,8 @@ public class SignatureAlgorithm extends Algorithm {
* @param len
* @throws XMLSignatureException
*/
public void update(byte buf[], int offset, int len)
throws XMLSignatureException {
this._signatureAlgorithm.engineUpdate(buf, offset, len);
public void update(byte buf[], int offset, int len) throws XMLSignatureException {
signatureAlgorithm.engineUpdate(buf, offset, len);
}
/**
......@@ -269,27 +239,20 @@ public class SignatureAlgorithm extends Algorithm {
* @throws XMLSignatureException
*/
public void initSign(Key signingKey) throws XMLSignatureException {
initializeAlgorithm(true);
Map<String, Key> map=keysSigning.get();
if (map.get(this.algorithmURI)==signingKey) {
return;
}
map.put(this.algorithmURI,signingKey);
this._signatureAlgorithm.engineInitSign(signingKey);
signatureAlgorithm.engineInitSign(signingKey);
}
/**
* Proxy method for {@link java.security.Signature#initSign(java.security.PrivateKey, java.security.SecureRandom)}
* Proxy method for {@link java.security.Signature#initSign(java.security.PrivateKey,
* java.security.SecureRandom)}
* which is executed on the internal {@link java.security.Signature} object.
*
* @param signingKey
* @param secureRandom
* @throws XMLSignatureException
*/
public void initSign(Key signingKey, SecureRandom secureRandom)
throws XMLSignatureException {
initializeAlgorithm(true);
this._signatureAlgorithm.engineInitSign(signingKey, secureRandom);
public void initSign(Key signingKey, SecureRandom secureRandom) throws XMLSignatureException {
signatureAlgorithm.engineInitSign(signingKey, secureRandom);
}
/**
......@@ -301,23 +264,21 @@ public class SignatureAlgorithm extends Algorithm {
* @throws XMLSignatureException
*/
public void initSign(
Key signingKey, AlgorithmParameterSpec algorithmParameterSpec)
throws XMLSignatureException {
initializeAlgorithm(true);
this._signatureAlgorithm.engineInitSign(signingKey,
algorithmParameterSpec);
Key signingKey, AlgorithmParameterSpec algorithmParameterSpec
) throws XMLSignatureException {
signatureAlgorithm.engineInitSign(signingKey, algorithmParameterSpec);
}
/**
* Proxy method for {@link java.security.Signature#setParameter(java.security.spec.AlgorithmParameterSpec)}
* Proxy method for {@link java.security.Signature#setParameter(
* java.security.spec.AlgorithmParameterSpec)}
* which is executed on the internal {@link java.security.Signature} object.
*
* @param params
* @throws XMLSignatureException
*/
public void setParameter(AlgorithmParameterSpec params)
throws XMLSignatureException {
this._signatureAlgorithm.engineSetParameter(params);
public void setParameter(AlgorithmParameterSpec params) throws XMLSignatureException {
signatureAlgorithm.engineSetParameter(params);
}
/**
......@@ -328,13 +289,7 @@ public class SignatureAlgorithm extends Algorithm {
* @throws XMLSignatureException
*/
public void initVerify(Key verificationKey) throws XMLSignatureException {
initializeAlgorithm(false);
Map<String, Key> map=keysVerify.get();
if (map.get(this.algorithmURI)==verificationKey) {
return;
}
map.put(this.algorithmURI,verificationKey);
this._signatureAlgorithm.engineInitVerify(verificationKey);
signatureAlgorithm.engineInitVerify(verificationKey);
}
/**
......@@ -347,7 +302,7 @@ public class SignatureAlgorithm extends Algorithm {
* @throws XMLSignatureException
*/
public boolean verify(byte[] signature) throws XMLSignatureException {
return this._signatureAlgorithm.engineVerify(signature);
return signatureAlgorithm.engineVerify(signature);
}
/**
......@@ -356,89 +311,120 @@ public class SignatureAlgorithm extends Algorithm {
* @return the URI representation of Transformation algorithm
*/
public final String getURI() {
return this._constructionElement.getAttributeNS(null,
Constants._ATT_ALGORITHM);
}
/**
* Initalizes for this {@link com.sun.org.apache.xml.internal.security.transforms.Transform}
*
*/
public static void providerInit() {
if (SignatureAlgorithm.log == null) {
SignatureAlgorithm.log =
java.util.logging.Logger
.getLogger(SignatureAlgorithm.class.getName());
}
log.log(java.util.logging.Level.FINE, "Init() called");
if (!SignatureAlgorithm._alreadyInitialized) {
SignatureAlgorithm._algorithmHash = new HashMap<String, Class<? extends SignatureAlgorithmSpi>>(10);
SignatureAlgorithm._alreadyInitialized = true;
}
return _constructionElement.getAttributeNS(null, Constants._ATT_ALGORITHM);
}
/**
* Registers implementing class of the Transform algorithm with algorithmURI
*
* @param algorithmURI algorithmURI URI representation of <code>Transform algorithm</code>.
* @param implementingClass <code>implementingClass</code> the implementing class of {@link SignatureAlgorithmSpi}
* @param implementingClass <code>implementingClass</code> the implementing class of
* {@link SignatureAlgorithmSpi}
* @throws AlgorithmAlreadyRegisteredException if specified algorithmURI is already registered
* @throws XMLSignatureException
*/
@SuppressWarnings("unchecked")
public static void register(String algorithmURI, String implementingClass)
throws AlgorithmAlreadyRegisteredException,XMLSignatureException {
{
if (log.isLoggable(java.util.logging.Level.FINE))
throws AlgorithmAlreadyRegisteredException, ClassNotFoundException,
XMLSignatureException {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Try to register " + algorithmURI + " " + implementingClass);
}
// are we already registered?
Class<? extends SignatureAlgorithmSpi> registeredClassClass =
SignatureAlgorithm.getImplementingClass(algorithmURI);
if (registeredClassClass!=null) {
String registeredClass = registeredClassClass.getName();
if ((registeredClass != null) && (registeredClass.length() != 0)) {
Class<? extends SignatureAlgorithmSpi> registeredClass = algorithmHash.get(algorithmURI);
if (registeredClass != null) {
Object exArgs[] = { algorithmURI, registeredClass };
throw new AlgorithmAlreadyRegisteredException(
"algorithm.alreadyRegistered", exArgs);
}
"algorithm.alreadyRegistered", exArgs
);
}
try {
SignatureAlgorithm._algorithmHash.put(algorithmURI, (Class <? extends SignatureAlgorithmSpi>)Class.forName(implementingClass));
} catch (ClassNotFoundException ex) {
Object exArgs[] = { algorithmURI, ex.getMessage() };
throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs,
ex);
Class<? extends SignatureAlgorithmSpi> clazz =
(Class<? extends SignatureAlgorithmSpi>)
ClassLoaderUtils.loadClass(implementingClass, SignatureAlgorithm.class);
algorithmHash.put(algorithmURI, clazz);
} catch (NullPointerException ex) {
Object exArgs[] = { algorithmURI, ex.getMessage() };
throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs,
ex);
}
throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs, ex);
}
}
/**
* Method getImplementingClass
* Registers implementing class of the Transform algorithm with algorithmURI
*
* @param URI
* @return the class that implements the URI
* @param algorithmURI algorithmURI URI representation of <code>Transform algorithm</code>.
* @param implementingClass <code>implementingClass</code> the implementing class of
* {@link SignatureAlgorithmSpi}
* @throws AlgorithmAlreadyRegisteredException if specified algorithmURI is already registered
* @throws XMLSignatureException
*/
private static Class<? extends SignatureAlgorithmSpi> getImplementingClass(String URI) {
public static void register(String algorithmURI, Class<? extends SignatureAlgorithmSpi> implementingClass)
throws AlgorithmAlreadyRegisteredException, ClassNotFoundException,
XMLSignatureException {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Try to register " + algorithmURI + " " + implementingClass);
}
if (SignatureAlgorithm._algorithmHash == null) {
return null;
// are we already registered?
Class<? extends SignatureAlgorithmSpi> registeredClass = algorithmHash.get(algorithmURI);
if (registeredClass != null) {
Object exArgs[] = { algorithmURI, registeredClass };
throw new AlgorithmAlreadyRegisteredException(
"algorithm.alreadyRegistered", exArgs
);
}
algorithmHash.put(algorithmURI, implementingClass);
}
return SignatureAlgorithm._algorithmHash.get(URI);
/**
* This method registers the default algorithms.
*/
public static void registerDefaultAlgorithms() {
algorithmHash.put(
XMLSignature.ALGO_ID_SIGNATURE_DSA, SignatureDSA.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1, SignatureBaseRSA.SignatureRSASHA1.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_MAC_HMAC_SHA1, IntegrityHmac.IntegrityHmacSHA1.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5,
SignatureBaseRSA.SignatureRSAMD5.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_SIGNATURE_RSA_RIPEMD160,
SignatureBaseRSA.SignatureRSARIPEMD160.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256, SignatureBaseRSA.SignatureRSASHA256.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384, SignatureBaseRSA.SignatureRSASHA384.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512, SignatureBaseRSA.SignatureRSASHA512.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA1, SignatureECDSA.SignatureECDSASHA1.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5, IntegrityHmac.IntegrityHmacMD5.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_MAC_HMAC_RIPEMD160, IntegrityHmac.IntegrityHmacRIPEMD160.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_MAC_HMAC_SHA256, IntegrityHmac.IntegrityHmacSHA256.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_MAC_HMAC_SHA384, IntegrityHmac.IntegrityHmacSHA384.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_MAC_HMAC_SHA512, IntegrityHmac.IntegrityHmacSHA512.class
);
}
/**
......
......@@ -2,34 +2,43 @@
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 1999-2008 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.sun.org.apache.xml.internal.security.c14n;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer11_OmitComments;
import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer11_WithComments;
import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315ExclOmitComments;
import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315ExclWithComments;
import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315OmitComments;
import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315WithComments;
import com.sun.org.apache.xml.internal.security.exceptions.AlgorithmAlreadyRegisteredException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
......@@ -46,7 +55,7 @@ public class Canonicalizer {
public static final String ENCODING = "UTF8";
/**
* XPath Expresion for selecting every node and continuous comments joined
* XPath Expression for selecting every node and continuous comments joined
* in only one node
*/
public static final String XPATH_C14N_WITH_COMMENTS_SINGLE_NODE =
......@@ -83,22 +92,10 @@ public class Canonicalizer {
public static final String ALGO_ID_C14N11_WITH_COMMENTS =
ALGO_ID_C14N11_OMIT_COMMENTS + "#WithComments";
static boolean _alreadyInitialized = false;
static Map<String,Class<? extends CanonicalizerSpi>> _canonicalizerHash = null;
protected CanonicalizerSpi canonicalizerSpi = null;
/**
* Method init
*
*/
public static void init() {
private static Map<String, Class<? extends CanonicalizerSpi>> canonicalizerHash =
new ConcurrentHashMap<String, Class<? extends CanonicalizerSpi>>();
if (!Canonicalizer._alreadyInitialized) {
Canonicalizer._canonicalizerHash = new HashMap<String, Class<? extends CanonicalizerSpi>>(10);
Canonicalizer._alreadyInitialized = true;
}
}
private final CanonicalizerSpi canonicalizerSpi;
/**
* Constructor Canonicalizer
......@@ -106,21 +103,18 @@ public class Canonicalizer {
* @param algorithmURI
* @throws InvalidCanonicalizerException
*/
private Canonicalizer(String algorithmURI)
throws InvalidCanonicalizerException {
private Canonicalizer(String algorithmURI) throws InvalidCanonicalizerException {
try {
Class<? extends CanonicalizerSpi> implementingClass =
getImplementingClass(algorithmURI);
canonicalizerHash.get(algorithmURI);
this.canonicalizerSpi =
implementingClass.newInstance();
this.canonicalizerSpi.reset=true;
canonicalizerSpi = implementingClass.newInstance();
canonicalizerSpi.reset = true;
} catch (Exception e) {
Object exArgs[] = { algorithmURI };
throw new InvalidCanonicalizerException(
"signature.Canonicalizer.UnknownCanonicalizer", exArgs);
"signature.Canonicalizer.UnknownCanonicalizer", exArgs, e
);
}
}
......@@ -128,15 +122,12 @@ public class Canonicalizer {
* Method getInstance
*
* @param algorithmURI
* @return a Conicicalizer instance ready for the job
* @return a Canonicalizer instance ready for the job
* @throws InvalidCanonicalizerException
*/
public static final Canonicalizer getInstance(String algorithmURI)
throws InvalidCanonicalizerException {
Canonicalizer c14nizer = new Canonicalizer(algorithmURI);
return c14nizer;
return new Canonicalizer(algorithmURI);
}
/**
......@@ -148,23 +139,69 @@ public class Canonicalizer {
*/
@SuppressWarnings("unchecked")
public static void register(String algorithmURI, String implementingClass)
throws AlgorithmAlreadyRegisteredException {
throws AlgorithmAlreadyRegisteredException, ClassNotFoundException {
// check whether URI is already registered
Class<? extends CanonicalizerSpi> registeredClass = getImplementingClass(algorithmURI);
Class<? extends CanonicalizerSpi> registeredClass =
canonicalizerHash.get(algorithmURI);
if (registeredClass != null) {
Object exArgs[] = { algorithmURI, registeredClass };
throw new AlgorithmAlreadyRegisteredException("algorithm.alreadyRegistered", exArgs);
}
throw new AlgorithmAlreadyRegisteredException(
"algorithm.alreadyRegistered", exArgs);
canonicalizerHash.put(
algorithmURI, (Class<? extends CanonicalizerSpi>)Class.forName(implementingClass)
);
}
try {
_canonicalizerHash.put(algorithmURI, (Class<? extends CanonicalizerSpi>) Class.forName(implementingClass));
} catch (ClassNotFoundException e) {
throw new RuntimeException("c14n class not found");
/**
* Method register
*
* @param algorithmURI
* @param implementingClass
* @throws AlgorithmAlreadyRegisteredException
*/
public static void register(String algorithmURI, Class<CanonicalizerSpi> implementingClass)
throws AlgorithmAlreadyRegisteredException, ClassNotFoundException {
// check whether URI is already registered
Class<? extends CanonicalizerSpi> registeredClass = canonicalizerHash.get(algorithmURI);
if (registeredClass != null) {
Object exArgs[] = { algorithmURI, registeredClass };
throw new AlgorithmAlreadyRegisteredException("algorithm.alreadyRegistered", exArgs);
}
canonicalizerHash.put(algorithmURI, implementingClass);
}
/**
* This method registers the default algorithms.
*/
public static void registerDefaultAlgorithms() {
canonicalizerHash.put(
Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS,
Canonicalizer20010315OmitComments.class
);
canonicalizerHash.put(
Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS,
Canonicalizer20010315WithComments.class
);
canonicalizerHash.put(
Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS,
Canonicalizer20010315ExclOmitComments.class
);
canonicalizerHash.put(
Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS,
Canonicalizer20010315ExclWithComments.class
);
canonicalizerHash.put(
Canonicalizer.ALGO_ID_C14N11_OMIT_COMMENTS,
Canonicalizer11_OmitComments.class
);
canonicalizerHash.put(
Canonicalizer.ALGO_ID_C14N11_WITH_COMMENTS,
Canonicalizer11_WithComments.class
);
}
/**
......@@ -173,7 +210,7 @@ public class Canonicalizer {
* @return the URI defined for this c14n instance.
*/
public final String getURI() {
return this.canonicalizerSpi.engineGetURI();
return canonicalizerSpi.engineGetURI();
}
/**
......@@ -182,7 +219,7 @@ public class Canonicalizer {
* @return true if the c14n respect the comments.
*/
public boolean getIncludeComments() {
return this.canonicalizerSpi.engineGetIncludeComments();
return canonicalizerSpi.engineGetIncludeComments();
}
/**
......@@ -191,7 +228,7 @@ public class Canonicalizer {
* wrapped with a <CODE>&gt;a&lt;...&gt;/a&lt;</CODE>.
*
* @param inputBytes
* @return the result of the conicalization.
* @return the result of the canonicalization.
* @throws CanonicalizationException
* @throws java.io.IOException
* @throws javax.xml.parsers.ParserConfigurationException
......@@ -199,25 +236,24 @@ public class Canonicalizer {
*/
public byte[] canonicalize(byte[] inputBytes)
throws javax.xml.parsers.ParserConfigurationException,
java.io.IOException, org.xml.sax.SAXException,
CanonicalizationException {
ByteArrayInputStream bais = new ByteArrayInputStream(inputBytes);
java.io.IOException, org.xml.sax.SAXException, CanonicalizationException {
InputStream bais = new ByteArrayInputStream(inputBytes);
InputSource in = new InputSource(bais);
DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
dfactory.setNamespaceAware(true);
// needs to validate for ID attribute nomalization
// needs to validate for ID attribute normalization
dfactory.setValidating(true);
DocumentBuilder db = dfactory.newDocumentBuilder();
/*
* for some of the test vectors from the specification,
* there has to be a validatin parser for ID attributes, default
* there has to be a validating parser for ID attributes, default
* attribute values, NMTOKENS, etc.
* Unfortunaltely, the test vectors do use different DTDs or
* Unfortunately, the test vectors do use different DTDs or
* even no DTD. So Xerces 1.3.1 fires many warnings about using
* ErrorHandlers.
*
......@@ -233,28 +269,23 @@ public class Canonicalizer {
* declaration are used to help create the canonical form, even
* though the document type declaration is not retained in the
* canonical form.
*
*/
db.setErrorHandler(new com.sun.org.apache.xml.internal.security.utils
.IgnoreAllErrorHandler());
db.setErrorHandler(new com.sun.org.apache.xml.internal.security.utils.IgnoreAllErrorHandler());
Document document = db.parse(in);
byte result[] = this.canonicalizeSubtree(document);
return result;
return this.canonicalizeSubtree(document);
}
/**
* Canonicalizes the subtree rooted by <CODE>node</CODE>.
*
* @param node The node to canicalize
* @param node The node to canonicalize
* @return the result of the c14n.
*
* @throws CanonicalizationException
*/
public byte[] canonicalizeSubtree(Node node)
throws CanonicalizationException {
return this.canonicalizerSpi.engineCanonicalizeSubTree(node);
public byte[] canonicalizeSubtree(Node node) throws CanonicalizationException {
return canonicalizerSpi.engineCanonicalizeSubTree(node);
}
/**
......@@ -267,8 +298,7 @@ public class Canonicalizer {
*/
public byte[] canonicalizeSubtree(Node node, String inclusiveNamespaces)
throws CanonicalizationException {
return this.canonicalizerSpi.engineCanonicalizeSubTree(node,
inclusiveNamespaces);
return canonicalizerSpi.engineCanonicalizeSubTree(node, inclusiveNamespaces);
}
/**
......@@ -281,7 +311,7 @@ public class Canonicalizer {
*/
public byte[] canonicalizeXPathNodeSet(NodeList xpathNodeSet)
throws CanonicalizationException {
return this.canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet);
return canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet);
}
/**
......@@ -294,10 +324,10 @@ public class Canonicalizer {
* @throws CanonicalizationException
*/
public byte[] canonicalizeXPathNodeSet(
NodeList xpathNodeSet, String inclusiveNamespaces)
throws CanonicalizationException {
return this.canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet,
inclusiveNamespaces);
NodeList xpathNodeSet, String inclusiveNamespaces
) throws CanonicalizationException {
return
canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet, inclusiveNamespaces);
}
/**
......@@ -309,7 +339,7 @@ public class Canonicalizer {
*/
public byte[] canonicalizeXPathNodeSet(Set<Node> xpathNodeSet)
throws CanonicalizationException {
return this.canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet);
return canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet);
}
/**
......@@ -320,10 +350,11 @@ public class Canonicalizer {
* @return the result of the c14n.
* @throws CanonicalizationException
*/
public byte[] canonicalizeXPathNodeSet(Set<Node> xpathNodeSet,
String inclusiveNamespaces) throws CanonicalizationException {
return this.canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet,
inclusiveNamespaces);
public byte[] canonicalizeXPathNodeSet(
Set<Node> xpathNodeSet, String inclusiveNamespaces
) throws CanonicalizationException {
return
canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet, inclusiveNamespaces);
}
/**
......@@ -332,7 +363,7 @@ public class Canonicalizer {
* @param os
*/
public void setWriter(OutputStream os) {
this.canonicalizerSpi.setWriter(os);
canonicalizerSpi.setWriter(os);
}
/**
......@@ -341,23 +372,14 @@ public class Canonicalizer {
* @return the name of the implementing {@link CanonicalizerSpi} class
*/
public String getImplementingCanonicalizerClass() {
return this.canonicalizerSpi.getClass().getName();
}
/**
* Method getImplementingClass
*
* @param URI
* @return the name of the class that implements the given URI
*/
private static Class<? extends CanonicalizerSpi> getImplementingClass(String URI) {
return _canonicalizerHash.get(URI);
return canonicalizerSpi.getClass().getName();
}
/**
* Set the canonicalizer behaviour to not reset.
*/
public void notReset() {
this.canonicalizerSpi.reset = false;
canonicalizerSpi.reset = false;
}
}
......@@ -26,6 +26,7 @@ import java.io.ByteArrayInputStream;
import java.io.OutputStream;
import java.util.Set;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
......@@ -67,6 +68,7 @@ public abstract class CanonicalizerSpi {
java.io.ByteArrayInputStream bais = new ByteArrayInputStream(inputBytes);
InputSource in = new InputSource(bais);
DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
// needs to validate for ID attribute nomalization
dfactory.setNamespaceAware(true);
......
......@@ -41,6 +41,7 @@ import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
......@@ -1982,6 +1983,7 @@ public class XMLCipher {
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
dbf.setAttribute("http://xml.org/sax/features/namespaces", Boolean.TRUE);
DocumentBuilder db = dbf.newDocumentBuilder();
Document d = db.parse(
......
......@@ -722,35 +722,29 @@ public class KeyInfo extends SignatureElementProxy {
/**
* Searches the library wide keyresolvers for public keys
*
* @return The publick contained in this Node.
* @return The public key contained in this Node.
* @throws KeyResolverException
*/
PublicKey getPublicKeyFromStaticResolvers() throws KeyResolverException {
int length=KeyResolver.length();
int storageLength=this._storageResolvers.size();
Iterator<KeyResolverSpi> it= KeyResolver.iterator();
for (int i = 0; i < length; i++) {
Iterator<KeyResolverSpi> it = KeyResolver.iterator();
while (it.hasNext()) {
KeyResolverSpi keyResolver = it.next();
Node currentChild=this._constructionElement.getFirstChild();
String uri= this.getBaseURI();
while (currentChild!=null) {
Node currentChild = this._constructionElement.getFirstChild();
String uri = this.getBaseURI();
while (currentChild != null) {
if (currentChild.getNodeType() == Node.ELEMENT_NODE) {
for (int k = 0; k < storageLength; k++) {
StorageResolver storage =
this._storageResolvers.get(k);
for (StorageResolver storage : _storageResolvers) {
PublicKey pk =
keyResolver.engineLookupAndResolvePublicKey((Element) currentChild,
uri,
storage);
keyResolver.engineLookupAndResolvePublicKey(
(Element) currentChild, uri, storage
);
if (pk != null) {
KeyResolver.hit(it);
return pk;
}
}
}
currentChild=currentChild.getNextSibling();
currentChild = currentChild.getNextSibling();
}
}
return null;
......@@ -834,47 +828,47 @@ public class KeyInfo extends SignatureElementProxy {
* child elements. Each combination of {@link KeyResolver} and child element
* is checked against all {@link StorageResolver}s.
*
* @return The certificate contined in this KeyInfo
* @return The certificate contained in this KeyInfo
* @throws KeyResolverException
*/
X509Certificate getX509CertificateFromStaticResolvers()
throws KeyResolverException {
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "Start getX509CertificateFromStaticResolvers() with "
+ KeyResolver.length() + " resolvers");
String uri=this.getBaseURI();
int length= KeyResolver.length();
int storageLength=this._storageResolvers.size();
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE,
"Start getX509CertificateFromStaticResolvers() with " + KeyResolver.length()
+ " resolvers"
);
}
String uri = this.getBaseURI();
Iterator<KeyResolverSpi> it = KeyResolver.iterator();
for (int i = 0; i <length; i++) {
while (it.hasNext()) {
KeyResolverSpi keyResolver = it.next();
X509Certificate cert= applyCurrentResolver(uri, storageLength, keyResolver);
if (cert!=null) {
KeyResolver.hit(it);
X509Certificate cert = applyCurrentResolver(uri, keyResolver);
if (cert != null) {
return cert;
}
}
return null;
}
private X509Certificate applyCurrentResolver(String uri, int storageLength, KeyResolverSpi keyResolver) throws KeyResolverException {
Node currentChild=this._constructionElement.getFirstChild();
while (currentChild!=null) {
private X509Certificate applyCurrentResolver(
String uri, KeyResolverSpi keyResolver
) throws KeyResolverException {
Node currentChild = this._constructionElement.getFirstChild();
while (currentChild != null) {
if (currentChild.getNodeType() == Node.ELEMENT_NODE) {
for (int k = 0; k < storageLength; k++) {
StorageResolver storage =
this._storageResolvers.get(k);
X509Certificate cert = keyResolver
.engineLookupResolveX509Certificate((Element) currentChild, uri,
storage);
for (StorageResolver storage : _storageResolvers) {
X509Certificate cert =
keyResolver.engineLookupResolveX509Certificate(
(Element) currentChild, uri, storage
);
if (cert != null) {
return cert;
}
}
}
currentChild=currentChild.getNextSibling();
currentChild = currentChild.getNextSibling();
}
return null;
}
......@@ -887,17 +881,19 @@ public class KeyInfo extends SignatureElementProxy {
*/
X509Certificate getX509CertificateFromInternalResolvers()
throws KeyResolverException {
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "Start getX509CertificateFromInternalResolvers() with "
+ this.lengthInternalKeyResolver() + " resolvers");
String uri=this.getBaseURI();
int storageLength=this._storageResolvers.size();
for (int i = 0; i < this.lengthInternalKeyResolver(); i++) {
KeyResolverSpi keyResolver = this.itemInternalKeyResolver(i);
if (log.isLoggable(java.util.logging.Level.FINE))
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE,
"Start getX509CertificateFromInternalResolvers() with "
+ this.lengthInternalKeyResolver() + " resolvers"
);
}
String uri = this.getBaseURI();
for (KeyResolverSpi keyResolver : _internalKeyResolvers) {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Try " + keyResolver.getClass().getName());
X509Certificate cert= applyCurrentResolver(uri, storageLength, keyResolver);
if (cert!=null) {
}
X509Certificate cert = applyCurrentResolver(uri, keyResolver);
if (cert != null) {
return cert;
}
}
......@@ -1048,7 +1044,7 @@ public class KeyInfo extends SignatureElementProxy {
}
/** Field _storageResolvers */
List<StorageResolver> _storageResolvers = nullList;
private List<StorageResolver> _storageResolvers = nullList;
/**
* Method addStorageResolver
......
......@@ -2,209 +2,216 @@
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.sun.org.apache.xml.internal.security.keys.keyresolver;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.crypto.SecretKey;
import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.DSAKeyValueResolver;
import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.RSAKeyValueResolver;
import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.RetrievalMethodResolver;
import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509CertificateResolver;
import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509IssuerSerialResolver;
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 org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* KeyResolver is factory class for subclass of KeyResolverSpi that
* represent child element of KeyInfo.
*
* @author $Author: mullan $
* @version %I%, %G%
*/
public class KeyResolver {
/** {@link java.util.logging} logging facility */
static java.util.logging.Logger log =
/** {@link org.apache.commons.logging} logging facility */
private static java.util.logging.Logger log =
java.util.logging.Logger.getLogger(KeyResolver.class.getName());
/** Field _alreadyInitialized */
static boolean _alreadyInitialized = false;
/** Field _resolverVector */
static List<KeyResolver> _resolverVector = null;
/** Field _resolverSpi */
protected KeyResolverSpi _resolverSpi = null;
/** Field resolverVector */
private static List<KeyResolver> resolverVector = new CopyOnWriteArrayList<KeyResolver>();
/** Field _storage */
protected StorageResolver _storage = null;
/** Field resolverSpi */
private final KeyResolverSpi resolverSpi;
/**
* Constructor ResourceResolver
* Constructor.
*
* @param className
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
* @param keyResolverSpi a KeyResolverSpi instance
*/
private KeyResolver(String className)
throws ClassNotFoundException, IllegalAccessException,
InstantiationException {
this._resolverSpi =
(KeyResolverSpi) Class.forName(className).newInstance();
this._resolverSpi.setGlobalResolver(true);
private KeyResolver(KeyResolverSpi keyResolverSpi) {
resolverSpi = keyResolverSpi;
}
/**
* Method length
*
* @return the length of resolvers registed
* @return the length of resolvers registered
*/
public static int length() {
return KeyResolver._resolverVector.size();
}
public static void hit(Iterator<KeyResolverSpi> hintI) {
ResolverIterator hint = (ResolverIterator) hintI;
int i = hint.i;
if (i!=1 && hint.res ==_resolverVector) {
List<KeyResolver> resolverVector=getResolverVectorClone();
KeyResolver ob=resolverVector.remove(i-1);
resolverVector.add(0,ob);
_resolverVector=resolverVector;
} else {
//System.out.println("KeyResolver hitting");
}
return resolverVector.size();
}
/**
* Method getInstance
* Method getX509Certificate
*
* @param element
* @param BaseURI
* @param baseURI
* @param storage
* @return The certificate represented by the element.
*
* @throws KeyResolverException
*/
public static final X509Certificate getX509Certificate(
Element element, String BaseURI, StorageResolver storage)
throws KeyResolverException {
// use the old vector to not be hit by updates
List<KeyResolver> resolverVector = KeyResolver._resolverVector;
Element element, String baseURI, StorageResolver storage
) throws KeyResolverException {
for (KeyResolver resolver : resolverVector) {
if (resolver==null) {
if (resolver == null) {
Object exArgs[] = {
(((element != null)
&& (element.getNodeType() == Node.ELEMENT_NODE))
? element.getTagName()
: "null") };
? element.getTagName() : "null")
};
throw new KeyResolverException("utils.resolver.noClass", exArgs);
}
if (log.isLoggable(java.util.logging.Level.FINE))
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "check resolvability by class " + resolver.getClass());
}
X509Certificate cert=resolver.resolveX509Certificate(element, BaseURI, storage);
if (cert!=null) {
X509Certificate cert = resolver.resolveX509Certificate(element, baseURI, storage);
if (cert != null) {
return cert;
}
}
Object exArgs[] = {
(((element != null) && (element.getNodeType() == Node.ELEMENT_NODE))
? element.getTagName()
: "null") };
? element.getTagName() : "null")
};
throw new KeyResolverException("utils.resolver.noClass", exArgs);
}
/**
* Method getInstance
* Method getPublicKey
*
* @param element
* @param BaseURI
* @param baseURI
* @param storage
* @return the public key contained in the element
*
* @throws KeyResolverException
*/
public static final PublicKey getPublicKey(
Element element, String BaseURI, StorageResolver storage)
throws KeyResolverException {
List<KeyResolver> resolverVector = KeyResolver._resolverVector;
Element element, String baseURI, StorageResolver storage
) throws KeyResolverException {
for (KeyResolver resolver : resolverVector) {
if (resolver==null) {
if (resolver == null) {
Object exArgs[] = {
(((element != null)
&& (element.getNodeType() == Node.ELEMENT_NODE))
? element.getTagName()
: "null") };
? element.getTagName() : "null")
};
throw new KeyResolverException("utils.resolver.noClass", exArgs);
}
if (log.isLoggable(java.util.logging.Level.FINE))
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "check resolvability by class " + resolver.getClass());
PublicKey cert=resolver.resolvePublicKey(element, BaseURI, storage);
if (cert!=null) {
if (resolverVector.indexOf(resolver)!=0 && resolverVector==_resolverVector) {
//update resolver.
resolverVector=getResolverVectorClone();
resolverVector.remove(resolver);
resolverVector.add(0,resolver);
_resolverVector=resolverVector;
}
PublicKey cert = resolver.resolvePublicKey(element, baseURI, storage);
if (cert != null) {
return cert;
}
}
Object exArgs[] = {
(((element != null) && (element.getNodeType() == Node.ELEMENT_NODE))
? element.getTagName()
: "null") };
? element.getTagName() : "null")
};
throw new KeyResolverException("utils.resolver.noClass", exArgs);
}
@SuppressWarnings("unchecked")
private static List<KeyResolver> getResolverVectorClone() {
return (List<KeyResolver>)((ArrayList<KeyResolver>)_resolverVector).clone();
/**
* This method is used for registering {@link KeyResolverSpi}s which are
* available to <I>all</I> {@link com.sun.org.apache.xml.internal.security.keys.KeyInfo} objects. This means that
* personalized {@link KeyResolverSpi}s should only be registered directly
* to the {@link com.sun.org.apache.xml.internal.security.keys.KeyInfo} using
* {@link com.sun.org.apache.xml.internal.security.keys.KeyInfo#registerInternalKeyResolver}.
* Please note that this method will create a new copy of the underlying array, as the
* underlying collection is a CopyOnWriteArrayList.
*
* @param className
* @param globalResolver Whether the KeyResolverSpi is a global resolver or not
* @throws InstantiationException
* @throws IllegalAccessException
* @throws ClassNotFoundException
*/
public static void register(String className, boolean globalResolver)
throws ClassNotFoundException, IllegalAccessException, InstantiationException {
KeyResolverSpi keyResolverSpi =
(KeyResolverSpi) Class.forName(className).newInstance();
keyResolverSpi.setGlobalResolver(globalResolver);
register(keyResolverSpi, false);
}
/**
* The init() function is called by com.sun.org.apache.xml.internal.security.Init.init()
* This method is used for registering {@link KeyResolverSpi}s which are
* available to <I>all</I> {@link com.sun.org.apache.xml.internal.security.keys.KeyInfo} objects. This means that
* personalized {@link KeyResolverSpi}s should only be registered directly
* to the {@link com.sun.org.apache.xml.internal.security.keys.KeyInfo} using
* {@link com.sun.org.apache.xml.internal.security.keys.KeyInfo#registerInternalKeyResolver}.
* Please note that this method will create a new copy of the underlying array, as the
* underlying collection is a CopyOnWriteArrayList.
*
* @param className
* @param globalResolver Whether the KeyResolverSpi is a global resolver or not
*/
public static void init() {
public static void registerAtStart(String className, boolean globalResolver) {
KeyResolverSpi keyResolverSpi = null;
Exception ex = null;
try {
keyResolverSpi = (KeyResolverSpi) Class.forName(className).newInstance();
} catch (ClassNotFoundException e) {
ex = e;
} catch (IllegalAccessException e) {
ex = e;
} catch (InstantiationException e) {
ex = e;
}
if (!KeyResolver._alreadyInitialized) {
KeyResolver._resolverVector = new ArrayList<KeyResolver>(10);
_alreadyInitialized = true;
if (ex != null) {
throw (IllegalArgumentException) new
IllegalArgumentException("Invalid KeyResolver class name").initCause(ex);
}
keyResolverSpi.setGlobalResolver(globalResolver);
register(keyResolverSpi, true);
}
/**
......@@ -213,73 +220,110 @@ public class KeyResolver {
* personalized {@link KeyResolverSpi}s should only be registered directly
* to the {@link com.sun.org.apache.xml.internal.security.keys.KeyInfo} using
* {@link com.sun.org.apache.xml.internal.security.keys.KeyInfo#registerInternalKeyResolver}.
* Please note that this method will create a new copy of the underlying array, as the
* underlying collection is a CopyOnWriteArrayList.
*
* @param className
* @throws InstantiationException
* @throws IllegalAccessException
* @throws ClassNotFoundException
* @param keyResolverSpi a KeyResolverSpi instance to register
* @param start whether to register the KeyResolverSpi at the start of the list or not
*/
public static void register(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
KeyResolver._resolverVector.add(new KeyResolver(className));
public static void register(
KeyResolverSpi keyResolverSpi,
boolean start
) {
KeyResolver resolver = new KeyResolver(keyResolverSpi);
if (start) {
resolverVector.add(0, resolver);
} else {
resolverVector.add(resolver);
}
}
/**
* This method is used for registering {@link KeyResolverSpi}s which are
* available to <I>all</I> {@link com.sun.org.apache.xml.internal.security.keys.KeyInfo} objects. This means that
* personalized {@link KeyResolverSpi}s should only be registered directly
* to the {@link com.sun.org.apache.xml.internal.security.keys.KeyInfo} using {@link com.sun.org.apache.xml.internal.security.keys.KeyInfo#registerInternalKeyResolver}.
* to the {@link com.sun.org.apache.xml.internal.security.keys.KeyInfo} using
* {@link com.sun.org.apache.xml.internal.security.keys.KeyInfo#registerInternalKeyResolver}.
* The KeyResolverSpi instances are not registered as a global resolver.
*
* @param className
*
* @param classNames
* @throws InstantiationException
* @throws IllegalAccessException
* @throws ClassNotFoundException
*/
public static void registerAtStart(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
register(className);
public static void registerClassNames(List<String> classNames)
throws ClassNotFoundException, IllegalAccessException, InstantiationException {
List<KeyResolver> keyResolverList = new ArrayList<KeyResolver>(classNames.size());
for (String className : classNames) {
KeyResolverSpi keyResolverSpi =
(KeyResolverSpi) Class.forName(className).newInstance();
keyResolverSpi.setGlobalResolver(false);
keyResolverList.add(new KeyResolver(keyResolverSpi));
}
resolverVector.addAll(keyResolverList);
}
/**
* Method resolve
* This method registers the default resolvers.
*/
public static void registerDefaultResolvers() {
List<KeyResolver> keyResolverList = new ArrayList<KeyResolver>();
keyResolverList.add(new KeyResolver(new RSAKeyValueResolver()));
keyResolverList.add(new KeyResolver(new DSAKeyValueResolver()));
keyResolverList.add(new KeyResolver(new X509CertificateResolver()));
keyResolverList.add(new KeyResolver(new X509SKIResolver()));
keyResolverList.add(new KeyResolver(new RetrievalMethodResolver()));
keyResolverList.add(new KeyResolver(new X509SubjectNameResolver()));
keyResolverList.add(new KeyResolver(new X509IssuerSerialResolver()));
resolverVector.addAll(keyResolverList);
}
/**
* Method resolvePublicKey
*
* @param element
* @param BaseURI
* @param baseURI
* @param storage
* @return resolved public key from the registered from the elements
*
* @throws KeyResolverException
*/
public PublicKey resolvePublicKey(
Element element, String BaseURI, StorageResolver storage)
throws KeyResolverException {
return this._resolverSpi.engineLookupAndResolvePublicKey(element, BaseURI, storage);
Element element, String baseURI, StorageResolver storage
) throws KeyResolverException {
return resolverSpi.engineLookupAndResolvePublicKey(element, baseURI, storage);
}
/**
* Method resolveX509Certificate
*
* @param element
* @param BaseURI
* @param baseURI
* @param storage
* @return resolved X509certificate key from the registered from the elements
*
* @throws KeyResolverException
*/
public X509Certificate resolveX509Certificate(
Element element, String BaseURI, StorageResolver storage)
throws KeyResolverException {
return this._resolverSpi.engineLookupResolveX509Certificate(element, BaseURI,
storage);
Element element, String baseURI, StorageResolver storage
) throws KeyResolverException {
return resolverSpi.engineLookupResolveX509Certificate(element, baseURI, storage);
}
/**
* @param element
* @param BaseURI
* @param baseURI
* @param storage
* @return resolved SecretKey key from the registered from the elements
* @throws KeyResolverException
*/
public SecretKey resolveSecretKey(
Element element, String BaseURI, StorageResolver storage)
throws KeyResolverException {
return this._resolverSpi.engineLookupAndResolveSecretKey(element, BaseURI,
storage);
Element element, String baseURI, StorageResolver storage
) throws KeyResolverException {
return resolverSpi.engineLookupAndResolveSecretKey(element, baseURI, storage);
}
/**
......@@ -289,17 +333,17 @@ public class KeyResolver {
* @param value
*/
public void setProperty(String key, String value) {
this._resolverSpi.engineSetProperty(key, value);
resolverSpi.engineSetProperty(key, value);
}
/**
* Method getProperty
*
* @param key
* @return the property setted for this resolver
* @return the property set for this resolver
*/
public String getProperty(String key) {
return this._resolverSpi.engineGetProperty(key);
return resolverSpi.engineGetProperty(key);
}
......@@ -310,7 +354,7 @@ public class KeyResolver {
* @return true if the resolver understands property propertyToTest
*/
public boolean understandsProperty(String propertyToTest) {
return this._resolverSpi.understandsProperty(propertyToTest);
return resolverSpi.understandsProperty(propertyToTest);
}
......@@ -320,39 +364,40 @@ public class KeyResolver {
* @return the name of the resolver.
*/
public String resolverClassName() {
return this._resolverSpi.getClass().getName();
return resolverSpi.getClass().getName();
}
/**
* Iterate over the KeyResolverSpi instances
*/
static class ResolverIterator implements Iterator<KeyResolverSpi> {
List<KeyResolver> res;
Iterator<KeyResolver> it;
int i;
public ResolverIterator(List<KeyResolver> list) {
res = list;
it = res.iterator();
}
public boolean hasNext() {
// TODO Auto-generated method stub
return it.hasNext();
}
public KeyResolverSpi next() {
i++;
KeyResolver resolver = it.next();
if (resolver==null) {
if (resolver == null) {
throw new RuntimeException("utils.resolver.noClass");
}
return resolver._resolverSpi;
return resolver.resolverSpi;
}
public void remove() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Can't remove resolvers using the iterator");
}
};
public static Iterator<KeyResolverSpi> iterator() {
return new ResolverIterator(_resolverVector);
return new ResolverIterator(resolverVector);
}
}
......@@ -34,6 +34,7 @@ import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import javax.xml.XMLConstants;
import javax.xml.parsers.ParserConfigurationException;
import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
......@@ -251,6 +252,7 @@ public class RetrievalMethodResolver extends KeyResolverSpi {
try {
javax.xml.parsers.DocumentBuilderFactory dbf =javax.xml.parsers.DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
org.w3c.dom.Document doc =
db.parse(new java.io.ByteArrayInputStream(bytes));
......
......@@ -88,6 +88,8 @@ prefix.AlreadyAssigned = You want to assign {0} as prefix for namespace {1} but
signature.Canonicalizer.UnknownCanonicalizer = Unknown canonicalizer. No handler installed for URI {0}
signature.DSA.invalidFormat = Invalid ASN.1 encoding of the DSA signature
signature.Generation.signBeforeGetValue = You have to XMLSignature.sign(java.security.PrivateKey) first
signature.Reference.ForbiddenResolver = It is forbidden to access resolver {0} when secure validation is enabled
signature.signatureAlgorithm = It is forbidden to use algorithm {0} when secure validation is enabled
signature.signaturePropertyHasNoTarget = The Target attribute of the SignatureProperty must be set
signature.Transform.ErrorDuringTransform = A {1} was thrown during the {0} transform
signature.Transform.NotYetImplemented = Transform {0} not yet implemented
......@@ -105,6 +107,7 @@ signature.Verification.InvalidDigestOrReference = Invalid digest of reference {0
signature.Verification.keyStore = KeyStore error
signature.Verification.MissingID = Cannot resolve element with ID {0}
signature.Verification.MissingResources = Cannot resolve external resource {0}
signature.Verification.MultipleIDs = Multiple Elements with the same ID {0} were detected
signature.Verification.NoSignatureElement = Input document contains no {0} Element in namespace {1}
signature.Verification.Reference.NoInput = The Reference for URI {0} has no XMLSignatureInput
signature.Verification.SignatureError = Signature error
......
......@@ -25,6 +25,7 @@ import java.io.IOException;
import java.io.OutputStream;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.XMLConstants;
import javax.xml.parsers.ParserConfigurationException;
import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithm;
......@@ -186,8 +187,10 @@ public class SignedInfo extends Manifest {
javax.xml.parsers.DocumentBuilderFactory dbf =
javax.xml.parsers.DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,
Boolean.TRUE);
javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
org.w3c.dom.Document newdoc =
Document newdoc =
db.parse(new ByteArrayInputStream(this._c14nizedBytes));
Node imported =
this._doc.importNode(newdoc.getDocumentElement(), true);
......
......@@ -201,14 +201,13 @@ private Element signatureValueElement;
super(doc);
String xmlnsDsPrefix =
getDefaultPrefixBindings(Constants.SignatureSpecNS);
String xmlnsDsPrefix = getDefaultPrefix(Constants.SignatureSpecNS);
if (xmlnsDsPrefix == null) {
this._constructionElement.setAttributeNS
(Constants.NamespaceSpecNS, "xmlns", Constants.SignatureSpecNS);
} else {
this._constructionElement.setAttributeNS
(Constants.NamespaceSpecNS, xmlnsDsPrefix, Constants.SignatureSpecNS);
(Constants.NamespaceSpecNS, "xmlns:" + xmlnsDsPrefix, Constants.SignatureSpecNS);
}
XMLUtils.addReturnToElement(this._constructionElement);
......@@ -242,14 +241,13 @@ private Element signatureValueElement;
super(doc);
String xmlnsDsPrefix =
getDefaultPrefixBindings(Constants.SignatureSpecNS);
String xmlnsDsPrefix = getDefaultPrefix(Constants.SignatureSpecNS);
if (xmlnsDsPrefix == null) {
this._constructionElement.setAttributeNS
(Constants.NamespaceSpecNS, "xmlns", Constants.SignatureSpecNS);
} else {
this._constructionElement.setAttributeNS
(Constants.NamespaceSpecNS, xmlnsDsPrefix, Constants.SignatureSpecNS);
(Constants.NamespaceSpecNS, "xmlns:" + xmlnsDsPrefix, Constants.SignatureSpecNS);
}
XMLUtils.addReturnToElement(this._constructionElement);
......
......@@ -31,6 +31,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
......@@ -603,6 +604,8 @@ public class XMLSignatureInput implements Cloneable {
DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
dfactory.setValidating(false);
dfactory.setNamespaceAware(true);
dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,
Boolean.TRUE);
DocumentBuilder db = dfactory.newDocumentBuilder();
// select all nodes, also the comments.
try {
......
......@@ -2,29 +2,29 @@
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.sun.org.apache.xml.internal.security.transforms;
import java.io.IOException;
import java.io.OutputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
......@@ -33,6 +33,18 @@ import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerExcepti
import com.sun.org.apache.xml.internal.security.exceptions.AlgorithmAlreadyRegisteredException;
import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
import com.sun.org.apache.xml.internal.security.transforms.implementations.TransformBase64Decode;
import com.sun.org.apache.xml.internal.security.transforms.implementations.TransformC14N;
import com.sun.org.apache.xml.internal.security.transforms.implementations.TransformC14N11;
import com.sun.org.apache.xml.internal.security.transforms.implementations.TransformC14N11_WithComments;
import com.sun.org.apache.xml.internal.security.transforms.implementations.TransformC14NExclusive;
import com.sun.org.apache.xml.internal.security.transforms.implementations.TransformC14NExclusiveWithComments;
import com.sun.org.apache.xml.internal.security.transforms.implementations.TransformC14NWithComments;
import com.sun.org.apache.xml.internal.security.transforms.implementations.TransformEnvelopedSignature;
import com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXPath;
import com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXPath2Filter;
import com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT;
import com.sun.org.apache.xml.internal.security.utils.ClassLoaderUtils;
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.SignatureElementProxy;
......@@ -54,112 +66,31 @@ import org.xml.sax.SAXException;
* @author Christian Geuer-Pollmann
* @see Transforms
* @see TransformSpi
*
*/
public final class Transform extends SignatureElementProxy {
/** {@link java.util.logging} logging facility */
static java.util.logging.Logger log =
/** {@link org.apache.commons.logging} logging facility */
private static java.util.logging.Logger log =
java.util.logging.Logger.getLogger(Transform.class.getName());
/** Field _alreadyInitialized */
private static boolean alreadyInitialized = false;
/** All available Transform classes are registered here */
private static Map<String, Class<?>> transformClassHash = null;
private static Map<String, TransformSpi> transformSpiHash = new HashMap<String, TransformSpi>();
private TransformSpi transformSpi = null;
/**
* Constructs {@link Transform}
*
* @param doc the {@link Document} in which <code>Transform</code> will be
* placed
* @param algorithmURI URI representation of
* <code>Transform algorithm</code> which will be specified as parameter of
* {@link #getInstance(Document, String)}, when generated. </br>
* @param contextNodes the child node list of <code>Transform</code> element
* @throws InvalidTransformException
*/
public Transform(Document doc, String algorithmURI, NodeList contextNodes)
throws InvalidTransformException {
super(doc);
this._constructionElement.setAttributeNS
(null, Constants._ATT_ALGORITHM, algorithmURI);
transformSpi = getTransformSpi(algorithmURI);
if (transformSpi == null) {
Object exArgs[] = { algorithmURI };
throw new InvalidTransformException(
"signature.Transform.UnknownTransform", exArgs);
}
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Create URI \"" + algorithmURI + "\" class \""
+ transformSpi.getClass() + "\"");
log.log(java.util.logging.Level.FINE, "The NodeList is " + contextNodes);
}
// give it to the current document
if (contextNodes != null) {
for (int i = 0; i < contextNodes.getLength(); i++) {
this._constructionElement.appendChild
(contextNodes.item(i).cloneNode(true));
}
}
}
/**
* This constructor can only be called from the {@link Transforms} object,
* so it's protected.
*
* @param element <code>ds:Transform</code> element
* @param BaseURI the URI of the resource where the XML instance was stored
* @throws InvalidTransformException
* @throws TransformationException
* @throws XMLSecurityException
*/
public Transform(Element element, String BaseURI)
throws InvalidTransformException, TransformationException,
XMLSecurityException {
super(element, BaseURI);
private static Map<String, Class<? extends TransformSpi>> transformSpiHash =
new ConcurrentHashMap<String, Class<? extends TransformSpi>>();
// retrieve Algorithm Attribute from ds:Transform
String algorithmURI = element.getAttributeNS(null, Constants._ATT_ALGORITHM);
if (algorithmURI == null || algorithmURI.length() == 0) {
Object exArgs[] = { Constants._ATT_ALGORITHM,
Constants._TAG_TRANSFORM };
throw new TransformationException("xml.WrongContent", exArgs);
}
transformSpi = getTransformSpi(algorithmURI);
if (transformSpi == null) {
Object exArgs[] = { algorithmURI };
throw new InvalidTransformException(
"signature.Transform.UnknownTransform", exArgs);
}
}
private final TransformSpi transformSpi;
/**
* Generates a Transform object that implements the specified
* <code>Transform algorithm</code> URI.
*
* @param doc the proxy {@link Document}
* @param algorithmURI <code>Transform algorithm</code> URI representation,
* such as specified in
* <a href=http://www.w3.org/TR/xmldsig-core/#sec-TransformAlg>Transform algorithm </a>
* @param doc the proxy {@link Document}
* @return <code>{@link Transform}</code> object
* @throws InvalidTransformException
*/
public static Transform getInstance(
Document doc, String algorithmURI) throws InvalidTransformException {
return getInstance(doc, algorithmURI, (NodeList) null);
public Transform(Document doc, String algorithmURI) throws InvalidTransformException {
this(doc, algorithmURI, (NodeList)null);
}
/**
......@@ -171,82 +102,160 @@ public final class Transform extends SignatureElementProxy {
* <a href=http://www.w3.org/TR/xmldsig-core/#sec-TransformAlg>Transform algorithm </a>
* @param contextChild the child element of <code>Transform</code> element
* @param doc the proxy {@link Document}
* @return <code>{@link Transform}</code> object
* @throws InvalidTransformException
*/
public static Transform getInstance(
Document doc, String algorithmURI, Element contextChild)
public Transform(Document doc, String algorithmURI, Element contextChild)
throws InvalidTransformException {
super(doc);
HelperNodeList contextNodes = null;
HelperNodeList contextNodes = new HelperNodeList();
if (contextChild != null) {
contextNodes = new HelperNodeList();
XMLUtils.addReturnToElement(doc, contextNodes);
contextNodes.appendChild(contextChild);
XMLUtils.addReturnToElement(doc, contextNodes);
}
return getInstance(doc, algorithmURI, contextNodes);
transformSpi = initializeTransform(algorithmURI, contextNodes);
}
/**
* Generates a Transform object that implements the specified
* <code>Transform algorithm</code> URI.
* Constructs {@link Transform}
*
* @param algorithmURI <code>Transform algorithm</code> URI form, such as
* specified in <a href=http://www.w3.org/TR/xmldsig-core/#sec-TransformAlg>
* Transform algorithm </a>
* @param doc the {@link Document} in which <code>Transform</code> will be
* placed
* @param algorithmURI URI representation of <code>Transform algorithm</code>
* @param contextNodes the child node list of <code>Transform</code> element
* @param doc the proxy {@link Document}
* @return <code>{@link Transform}</code> object
* @throws InvalidTransformException
*/
public static Transform getInstance(
Document doc, String algorithmURI, NodeList contextNodes)
public Transform(Document doc, String algorithmURI, NodeList contextNodes)
throws InvalidTransformException {
return new Transform(doc, algorithmURI, contextNodes);
super(doc);
transformSpi = initializeTransform(algorithmURI, contextNodes);
}
/**
* Initalizes for this {@link Transform}.
* @param element <code>ds:Transform</code> element
* @param BaseURI the URI of the resource where the XML instance was stored
* @throws InvalidTransformException
* @throws TransformationException
* @throws XMLSecurityException
*/
public static void init() {
if (!alreadyInitialized) {
transformClassHash = new HashMap<String,Class<?>>(10);
// make sure builtin algorithms are all registered first
com.sun.org.apache.xml.internal.security.Init.init();
alreadyInitialized = true;
public Transform(Element element, String BaseURI)
throws InvalidTransformException, TransformationException, XMLSecurityException {
super(element, BaseURI);
// retrieve Algorithm Attribute from ds:Transform
String algorithmURI = element.getAttributeNS(null, Constants._ATT_ALGORITHM);
if (algorithmURI == null || algorithmURI.length() == 0) {
Object exArgs[] = { Constants._ATT_ALGORITHM, Constants._TAG_TRANSFORM };
throw new TransformationException("xml.WrongContent", exArgs);
}
Class<? extends TransformSpi> transformSpiClass = transformSpiHash.get(algorithmURI);
if (transformSpiClass == null) {
Object exArgs[] = { algorithmURI };
throw new InvalidTransformException("signature.Transform.UnknownTransform", exArgs);
}
try {
transformSpi = transformSpiClass.newInstance();
} catch (InstantiationException ex) {
Object exArgs[] = { algorithmURI };
throw new InvalidTransformException(
"signature.Transform.UnknownTransform", exArgs, ex
);
} catch (IllegalAccessException ex) {
Object exArgs[] = { algorithmURI };
throw new InvalidTransformException(
"signature.Transform.UnknownTransform", exArgs, ex
);
}
}
/**
* Registers implementing class of the Transform algorithm with algorithmURI
*
* @param algorithmURI algorithmURI URI representation of
* <code>Transform algorithm</code> will be specified as parameter of
* {@link #getInstance(Document, String)}, when generate. </br>
* @param algorithmURI algorithmURI URI representation of <code>Transform algorithm</code>
* @param implementingClass <code>implementingClass</code> the implementing
* class of {@link TransformSpi}
* @throws AlgorithmAlreadyRegisteredException if specified algorithmURI
* is already registered
*/
@SuppressWarnings("unchecked")
public static void register(String algorithmURI, String implementingClass)
throws AlgorithmAlreadyRegisteredException {
throws AlgorithmAlreadyRegisteredException, ClassNotFoundException,
InvalidTransformException {
// are we already registered?
Class<? extends TransformSpi> registeredClass = getImplementingClass(algorithmURI);
if ((registeredClass != null) ) {
Object exArgs[] = { algorithmURI, registeredClass };
throw new AlgorithmAlreadyRegisteredException(
"algorithm.alreadyRegistered", exArgs);
Class<? extends TransformSpi> transformSpi = transformSpiHash.get(algorithmURI);
if (transformSpi != null) {
Object exArgs[] = { algorithmURI, transformSpi };
throw new AlgorithmAlreadyRegisteredException("algorithm.alreadyRegistered", exArgs);
}
Class<? extends TransformSpi> transformSpiClass =
(Class<? extends TransformSpi>)
ClassLoaderUtils.loadClass(implementingClass, Transform.class);
transformSpiHash.put(algorithmURI, transformSpiClass);
}
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try {
transformClassHash.put
(algorithmURI, Class.forName(implementingClass, true, cl));
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
/**
* Registers implementing class of the Transform algorithm with algorithmURI
*
* @param algorithmURI algorithmURI URI representation of <code>Transform algorithm</code>
* @param implementingClass <code>implementingClass</code> the implementing
* class of {@link TransformSpi}
* @throws AlgorithmAlreadyRegisteredException if specified algorithmURI
* is already registered
*/
public static void register(String algorithmURI, Class<? extends TransformSpi> implementingClass)
throws AlgorithmAlreadyRegisteredException {
// are we already registered?
Class<? extends TransformSpi> transformSpi = transformSpiHash.get(algorithmURI);
if (transformSpi != null) {
Object exArgs[] = { algorithmURI, transformSpi };
throw new AlgorithmAlreadyRegisteredException("algorithm.alreadyRegistered", exArgs);
}
transformSpiHash.put(algorithmURI, implementingClass);
}
/**
* This method registers the default algorithms.
*/
public static void registerDefaultAlgorithms() {
transformSpiHash.put(
Transforms.TRANSFORM_BASE64_DECODE, TransformBase64Decode.class
);
transformSpiHash.put(
Transforms.TRANSFORM_C14N_OMIT_COMMENTS, TransformC14N.class
);
transformSpiHash.put(
Transforms.TRANSFORM_C14N_WITH_COMMENTS, TransformC14NWithComments.class
);
transformSpiHash.put(
Transforms.TRANSFORM_C14N11_OMIT_COMMENTS, TransformC14N11.class
);
transformSpiHash.put(
Transforms.TRANSFORM_C14N11_WITH_COMMENTS, TransformC14N11_WithComments.class
);
transformSpiHash.put(
Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS, TransformC14NExclusive.class
);
transformSpiHash.put(
Transforms.TRANSFORM_C14N_EXCL_WITH_COMMENTS, TransformC14NExclusiveWithComments.class
);
transformSpiHash.put(
Transforms.TRANSFORM_XPATH, TransformXPath.class
);
transformSpiHash.put(
Transforms.TRANSFORM_ENVELOPED_SIGNATURE, TransformEnvelopedSignature.class
);
transformSpiHash.put(
Transforms.TRANSFORM_XSLT, TransformXSLT.class
);
transformSpiHash.put(
Transforms.TRANSFORM_XPATH2FILTER, TransformXPath2Filter.class
);
}
/**
......@@ -255,8 +264,7 @@ public final class Transform extends SignatureElementProxy {
* @return the URI representation of Transformation algorithm
*/
public String getURI() {
return this._constructionElement.getAttributeNS
(null, Constants._ATT_ALGORITHM);
return this._constructionElement.getAttributeNS(null, Constants._ATT_ALGORITHM);
}
/**
......@@ -274,28 +282,13 @@ public final class Transform extends SignatureElementProxy {
public XMLSignatureInput performTransform(XMLSignatureInput input)
throws IOException, CanonicalizationException,
InvalidCanonicalizerException, TransformationException {
XMLSignatureInput result = null;
try {
result = transformSpi.enginePerformTransform(input, this);
} catch (ParserConfigurationException ex) {
Object exArgs[] = { this.getURI(), "ParserConfigurationException" };
throw new CanonicalizationException(
"signature.Transform.ErrorDuringTransform", exArgs, ex);
} catch (SAXException ex) {
Object exArgs[] = { this.getURI(), "SAXException" };
throw new CanonicalizationException(
"signature.Transform.ErrorDuringTransform", exArgs, ex);
}
return result;
return performTransform(input, null);
}
/**
* Transforms the input, and generates {@link XMLSignatureInput} as output.
*
* @param input input {@link XMLSignatureInput} which can supplied Octet
* @param input input {@link XMLSignatureInput} which can supplied Octect
* Stream and NodeSet as Input of Transformation
* @param os where to output the result of the last transformation
* @return the {@link XMLSignatureInput} class as the result of
......@@ -305,10 +298,10 @@ public final class Transform extends SignatureElementProxy {
* @throws InvalidCanonicalizerException
* @throws TransformationException
*/
public XMLSignatureInput performTransform(XMLSignatureInput input,
OutputStream os) throws IOException, CanonicalizationException,
public XMLSignatureInput performTransform(
XMLSignatureInput input, OutputStream os
) throws IOException, CanonicalizationException,
InvalidCanonicalizerException, TransformationException {
XMLSignatureInput result = null;
try {
......@@ -326,44 +319,52 @@ public final class Transform extends SignatureElementProxy {
return result;
}
/**
* Method getImplementingClass
*
* @param URI
* @return The name of the class implementing the URI.
*/
@SuppressWarnings("unchecked")
private static Class<? extends TransformSpi> getImplementingClass(String URI) {
return (Class<? extends TransformSpi>)transformClassHash.get(URI);
/** @inheritDoc */
public String getBaseLocalName() {
return Constants._TAG_TRANSFORM;
}
private static TransformSpi getTransformSpi(String URI)
/**
* Initialize the transform object.
*/
private TransformSpi initializeTransform(String algorithmURI, NodeList contextNodes)
throws InvalidTransformException {
try {
TransformSpi value = transformSpiHash.get(URI);
if (value != null) {
return value;
}
Class<? extends TransformSpi> cl = getImplementingClass(URI);
if (cl != null) {
TransformSpi tr = cl.newInstance();
transformSpiHash.put(URI, tr);
return tr;
this._constructionElement.setAttributeNS(null, Constants._ATT_ALGORITHM, algorithmURI);
Class<? extends TransformSpi> transformSpiClass = transformSpiHash.get(algorithmURI);
if (transformSpiClass == null) {
Object exArgs[] = { algorithmURI };
throw new InvalidTransformException("signature.Transform.UnknownTransform", exArgs);
}
TransformSpi newTransformSpi = null;
try {
newTransformSpi = transformSpiClass.newInstance();
} catch (InstantiationException ex) {
Object exArgs[] = { URI };
Object exArgs[] = { algorithmURI };
throw new InvalidTransformException(
"signature.Transform.UnknownTransform", exArgs, ex);
"signature.Transform.UnknownTransform", exArgs, ex
);
} catch (IllegalAccessException ex) {
Object exArgs[] = { URI };
Object exArgs[] = { algorithmURI };
throw new InvalidTransformException(
"signature.Transform.UnknownTransform", exArgs, ex);
"signature.Transform.UnknownTransform", exArgs, ex
);
}
return null;
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Create URI \"" + algorithmURI + "\" class \""
+ newTransformSpi.getClass() + "\"");
log.log(java.util.logging.Level.FINE, "The NodeList is " + contextNodes);
}
/** @inheritDoc */
public String getBaseLocalName() {
return Constants._TAG_TRANSFORM;
// give it to the current document
if (contextNodes != null) {
for (int i = 0; i < contextNodes.getLength(); i++) {
this._constructionElement.appendChild(contextNodes.item(i).cloneNode(true));
}
}
return newTransformSpi;
}
}
......@@ -158,8 +158,7 @@ public class Transforms extends SignatureElementProxy {
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "Transforms.addTransform(" + transformURI + ")");
Transform transform =
Transform.getInstance(this._doc, transformURI);
Transform transform = new Transform(this._doc, transformURI);
this.addTransform(transform);
} catch (InvalidTransformException ex) {
......@@ -184,8 +183,7 @@ public class Transforms extends SignatureElementProxy {
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "Transforms.addTransform(" + transformURI + ")");
Transform transform =
Transform.getInstance(this._doc, transformURI, contextElement);
Transform transform = new Transform(this._doc, transformURI, contextElement);
this.addTransform(transform);
} catch (InvalidTransformException ex) {
......@@ -207,8 +205,7 @@ public class Transforms extends SignatureElementProxy {
throws TransformationException {
try {
Transform transform =
Transform.getInstance(this._doc, transformURI, contextNodes);
Transform transform = new Transform(this._doc, transformURI, contextNodes);
this.addTransform(transform);
} catch (InvalidTransformException ex) {
throw new TransformationException("empty", ex);
......
......@@ -26,6 +26,7 @@ import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
......@@ -145,11 +146,13 @@ public class TransformBase64Decode extends TransformSpi {
}
try {
//Exceptional case there is current not text case testing this(Before it was a
//a common case).
// Exceptional case there is current not text case testing this
// (before it was a a common case).
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,
Boolean.TRUE);
Document doc =
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
input.getOctetStream());
dbf.newDocumentBuilder().parse(input.getOctetStream());
Element rootNode = doc.getDocumentElement();
StringBuffer sb = new StringBuffer();
......
......@@ -26,6 +26,7 @@ import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method;
import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
......@@ -109,7 +110,8 @@ public class TransformXSLT extends TransformSpi {
TransformerFactory tFactory = TransformerFactory.newInstance();
// Process XSLT stylesheets in a secure manner
tFactory.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", Boolean.TRUE);
tFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,
Boolean.TRUE);
/*
* This transform requires an octet stream as input. If the actual
* input is an XPath node-set, then the signature application should
......
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.sun.org.apache.xml.internal.security.utils;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
/**
* This class is extremely useful for loading resources and classes in a fault
* tolerant manner that works across different applications servers. Do not
* touch this unless you're a grizzled classloading guru veteran who is going to
* verify any change on 6 different application servers.
*/
public final class ClassLoaderUtils {
/** {@link org.apache.commons.logging} logging facility */
private static final java.util.logging.Logger log =
java.util.logging.Logger.getLogger(ClassLoaderUtils.class.getName());
private ClassLoaderUtils() {
}
/**
* Load a given resource. <p/> This method will try to load the resource
* using the following methods (in order):
* <ul>
* <li>From Thread.currentThread().getContextClassLoader()
* <li>From ClassLoaderUtil.class.getClassLoader()
* <li>callingClass.getClassLoader()
* </ul>
*
* @param resourceName The name of the resource to load
* @param callingClass The Class object of the calling object
*/
public static URL getResource(String resourceName, Class<?> callingClass) {
URL url = Thread.currentThread().getContextClassLoader().getResource(resourceName);
if (url == null && resourceName.startsWith("/")) {
//certain classloaders need it without the leading /
url =
Thread.currentThread().getContextClassLoader().getResource(
resourceName.substring(1)
);
}
ClassLoader cluClassloader = ClassLoaderUtils.class.getClassLoader();
if (cluClassloader == null) {
cluClassloader = ClassLoader.getSystemClassLoader();
}
if (url == null) {
url = cluClassloader.getResource(resourceName);
}
if (url == null && resourceName.startsWith("/")) {
//certain classloaders need it without the leading /
url = cluClassloader.getResource(resourceName.substring(1));
}
if (url == null) {
ClassLoader cl = callingClass.getClassLoader();
if (cl != null) {
url = cl.getResource(resourceName);
}
}
if (url == null) {
url = callingClass.getResource(resourceName);
}
if ((url == null) && (resourceName != null) && (resourceName.charAt(0) != '/')) {
return getResource('/' + resourceName, callingClass);
}
return url;
}
/**
* Load a given resources. <p/> This method will try to load the resources
* using the following methods (in order):
* <ul>
* <li>From Thread.currentThread().getContextClassLoader()
* <li>From ClassLoaderUtil.class.getClassLoader()
* <li>callingClass.getClassLoader()
* </ul>
*
* @param resourceName The name of the resource to load
* @param callingClass The Class object of the calling object
*/
public static List<URL> getResources(String resourceName, Class<?> callingClass) {
List<URL> ret = new ArrayList<URL>();
Enumeration<URL> urls = new Enumeration<URL>() {
public boolean hasMoreElements() {
return false;
}
public URL nextElement() {
return null;
}
};
try {
urls = Thread.currentThread().getContextClassLoader().getResources(resourceName);
} catch (IOException e) {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, e.getMessage(), e);
}
//ignore
}
if (!urls.hasMoreElements() && resourceName.startsWith("/")) {
//certain classloaders need it without the leading /
try {
urls =
Thread.currentThread().getContextClassLoader().getResources(
resourceName.substring(1)
);
} catch (IOException e) {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, e.getMessage(), e);
}
// ignore
}
}
ClassLoader cluClassloader = ClassLoaderUtils.class.getClassLoader();
if (cluClassloader == null) {
cluClassloader = ClassLoader.getSystemClassLoader();
}
if (!urls.hasMoreElements()) {
try {
urls = cluClassloader.getResources(resourceName);
} catch (IOException e) {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, e.getMessage(), e);
}
// ignore
}
}
if (!urls.hasMoreElements() && resourceName.startsWith("/")) {
//certain classloaders need it without the leading /
try {
urls = cluClassloader.getResources(resourceName.substring(1));
} catch (IOException e) {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, e.getMessage(), e);
}
// ignore
}
}
if (!urls.hasMoreElements()) {
ClassLoader cl = callingClass.getClassLoader();
if (cl != null) {
try {
urls = cl.getResources(resourceName);
} catch (IOException e) {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, e.getMessage(), e);
}
// ignore
}
}
}
if (!urls.hasMoreElements()) {
URL url = callingClass.getResource(resourceName);
if (url != null) {
ret.add(url);
}
}
while (urls.hasMoreElements()) {
ret.add(urls.nextElement());
}
if (ret.isEmpty() && (resourceName != null) && (resourceName.charAt(0) != '/')) {
return getResources('/' + resourceName, callingClass);
}
return ret;
}
/**
* This is a convenience method to load a resource as a stream. <p/> The
* algorithm used to find the resource is given in getResource()
*
* @param resourceName The name of the resource to load
* @param callingClass The Class object of the calling object
*/
public static InputStream getResourceAsStream(String resourceName, Class<?> callingClass) {
URL url = getResource(resourceName, callingClass);
try {
return (url != null) ? url.openStream() : null;
} catch (IOException e) {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, e.getMessage(), e);
}
return null;
}
}
/**
* Load a class with a given name. <p/> It will try to load the class in the
* following order:
* <ul>
* <li>From Thread.currentThread().getContextClassLoader()
* <li>Using the basic Class.forName()
* <li>From ClassLoaderUtil.class.getClassLoader()
* <li>From the callingClass.getClassLoader()
* </ul>
*
* @param className The name of the class to load
* @param callingClass The Class object of the calling object
* @throws ClassNotFoundException If the class cannot be found anywhere.
*/
public static Class<?> loadClass(String className, Class<?> callingClass)
throws ClassNotFoundException {
try {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl != null) {
return cl.loadClass(className);
}
} catch (ClassNotFoundException e) {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, e.getMessage(), e);
}
//ignore
}
return loadClass2(className, callingClass);
}
private static Class<?> loadClass2(String className, Class<?> callingClass)
throws ClassNotFoundException {
try {
return Class.forName(className);
} catch (ClassNotFoundException ex) {
try {
if (ClassLoaderUtils.class.getClassLoader() != null) {
return ClassLoaderUtils.class.getClassLoader().loadClass(className);
}
} catch (ClassNotFoundException exc) {
if (callingClass != null && callingClass.getClassLoader() != null) {
return callingClass.getClassLoader().loadClass(className);
}
}
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, ex.getMessage(), ex);
}
throw ex;
}
}
}
......@@ -2,28 +2,28 @@
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 1999-2008 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.sun.org.apache.xml.internal.security.utils;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;
import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
......@@ -35,42 +35,27 @@ import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
/**
* This is the base class to all Objects which have a direct 1:1 mapping to an
* Element in a particular namespace.
*
* @author $Author: mullan $
*/
public abstract class ElementProxy {
/** {@link java.util.logging} logging facility */
static java.util.logging.Logger log =
protected static final java.util.logging.Logger log =
java.util.logging.Logger.getLogger(ElementProxy.class.getName());
/**
* Returns the namespace of the Elements of the sub-class.
*
* @return the namespace of the Elements of the sub-class.
*/
public abstract String getBaseNamespace();
/**
* Returns the localname of the Elements of the sub-class.
*
* @return the localname of the Elements of the sub-class.
*/
public abstract String getBaseLocalName();
/** Field _constructionElement */
/** Field constructionElement */
protected Element _constructionElement = null;
/** Field _baseURI */
/** Field baseURI */
protected String _baseURI = null;
/** Field _doc */
/** Field doc */
protected Document _doc = null;
/** Field prefixMappings */
private static Map<String, String> prefixMappings = new ConcurrentHashMap<String, String>();
/**
* Constructor ElementProxy
*
......@@ -89,37 +74,67 @@ public abstract class ElementProxy {
}
this._doc = doc;
this._constructionElement = createElementForFamilyLocal(this._doc,
this.getBaseNamespace(), this.getBaseLocalName());
this._constructionElement =
createElementForFamilyLocal(this._doc, this.getBaseNamespace(), this.getBaseLocalName());
}
protected Element createElementForFamilyLocal(Document doc, String namespace,
String localName) {
/**
* Constructor ElementProxy
*
* @param element
* @param BaseURI
* @throws XMLSecurityException
*/
public ElementProxy(Element element, String BaseURI) throws XMLSecurityException {
if (element == null) {
throw new XMLSecurityException("ElementProxy.nullElement");
}
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "setElement(\"" + element.getTagName() + "\", \"" + BaseURI + "\")");
}
this._doc = element.getOwnerDocument();
this._constructionElement = element;
this._baseURI = BaseURI;
this.guaranteeThatElementInCorrectSpace();
}
/**
* Returns the namespace of the Elements of the sub-class.
*
* @return the namespace of the Elements of the sub-class.
*/
public abstract String getBaseNamespace();
/**
* Returns the localname of the Elements of the sub-class.
*
* @return the localname of the Elements of the sub-class.
*/
public abstract String getBaseLocalName();
protected Element createElementForFamilyLocal(
Document doc, String namespace, String localName
) {
Element result = null;
if (namespace == null) {
result = doc.createElementNS(null, localName);
} else {
String baseName=this.getBaseNamespace();
String prefix=ElementProxy.getDefaultPrefix(baseName);
String baseName = this.getBaseNamespace();
String prefix = ElementProxy.getDefaultPrefix(baseName);
if ((prefix == null) || (prefix.length() == 0)) {
result = doc.createElementNS(namespace, localName);
result.setAttributeNS(Constants.NamespaceSpecNS, "xmlns",
namespace);
result.setAttributeNS(Constants.NamespaceSpecNS, "xmlns", namespace);
} else {
String tagName=null;
String defaultPrefixNaming=ElementProxy.getDefaultPrefixBindings(baseName);
StringBuffer sb=new StringBuffer(prefix);
sb.append(':');
sb.append(localName);
tagName=sb.toString();
result = doc.createElementNS(namespace, tagName );
result.setAttributeNS(Constants.NamespaceSpecNS, defaultPrefixNaming,
namespace);
result = doc.createElementNS(namespace, prefix + ":" + localName);
result.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:" + prefix, namespace);
}
}
return result;
}
}
/**
......@@ -134,9 +149,7 @@ public abstract class ElementProxy {
* @param localName
* @return The element created.
*/
public static Element createElementForFamily(Document doc, String namespace,
String localName) {
//Element nscontext = XMLUtils.createDSctx(doc, "x", namespace);
public static Element createElementForFamily(Document doc, String namespace, String localName) {
Element result = null;
String prefix = ElementProxy.getDefaultPrefix(namespace);
......@@ -145,14 +158,10 @@ public abstract class ElementProxy {
} else {
if ((prefix == null) || (prefix.length() == 0)) {
result = doc.createElementNS(namespace, localName);
result.setAttributeNS(Constants.NamespaceSpecNS, "xmlns",
namespace);
result.setAttributeNS(Constants.NamespaceSpecNS, "xmlns", namespace);
} else {
result = doc.createElementNS(namespace, prefix + ":" + localName);
result.setAttributeNS(Constants.NamespaceSpecNS, ElementProxy.getDefaultPrefixBindings(namespace),
namespace);
result.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:" + prefix, namespace);
}
}
......@@ -166,9 +175,7 @@ public abstract class ElementProxy {
* @param BaseURI
* @throws XMLSecurityException
*/
public void setElement(Element element, String BaseURI)
throws XMLSecurityException {
public void setElement(Element element, String BaseURI) throws XMLSecurityException {
if (element == null) {
throw new XMLSecurityException("ElementProxy.nullElement");
}
......@@ -182,30 +189,6 @@ public abstract class ElementProxy {
this._baseURI = BaseURI;
}
/**
* Constructor ElementProxy
*
* @param element
* @param BaseURI
* @throws XMLSecurityException
*/
public ElementProxy(Element element, String BaseURI)
throws XMLSecurityException {
if (element == null) {
throw new XMLSecurityException("ElementProxy.nullElement");
}
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "setElement(\"" + element.getTagName() + "\", \"" + BaseURI
+ "\")");
}
this._doc = element.getOwnerDocument();
this._constructionElement = element;
this._baseURI = BaseURI;
this.guaranteeThatElementInCorrectSpace();
}
/**
* Returns the Element which was constructed by the Object.
......@@ -250,31 +233,36 @@ public abstract class ElementProxy {
return this._baseURI;
}
static ElementChecker checker = new ElementCheckerImpl.InternedNsChecker();
/**
* Method guaranteeThatElementInCorrectSpace
*
* @throws XMLSecurityException
*/
void guaranteeThatElementInCorrectSpace()
throws XMLSecurityException {
void guaranteeThatElementInCorrectSpace() throws XMLSecurityException {
checker.guaranteeThatElementInCorrectSpace(this,this._constructionElement);
String expectedLocalName = this.getBaseLocalName();
String expectedNamespaceUri = this.getBaseNamespace();
String actualLocalName = this._constructionElement.getLocalName();
String actualNamespaceUri = this._constructionElement.getNamespaceURI();
if(!expectedNamespaceUri.equals(actualNamespaceUri)
&& !expectedLocalName.equals(actualLocalName)) {
Object exArgs[] = { actualNamespaceUri + ":" + actualLocalName,
expectedNamespaceUri + ":" + expectedLocalName};
throw new XMLSecurityException("xml.WrongElement", exArgs);
}
}
/**
* Method setVal
* Method addBigIntegerElement
*
* @param bi
* @param localname
*/
public void addBigIntegerElement(BigInteger bi, String localname) {
if (bi != null) {
Element e = XMLUtils.createElementInSignatureSpace(this._doc,
localname);
Element e = XMLUtils.createElementInSignatureSpace(this._doc, localname);
Base64.fillElementWithBigInteger(e, bi);
this._constructionElement.appendChild(e);
......@@ -289,9 +277,7 @@ public abstract class ElementProxy {
* @param localname
*/
public void addBase64Element(byte[] bytes, String localname) {
if (bytes != null) {
Element e = Base64.encodeToElement(this._doc, localname, bytes);
this._constructionElement.appendChild(e);
......@@ -308,7 +294,6 @@ public abstract class ElementProxy {
* @param localname
*/
public void addTextElement(String text, String localname) {
Element e = XMLUtils.createElementInSignatureSpace(this._doc, localname);
Text t = this._doc.createTextNode(text);
......@@ -323,7 +308,6 @@ public abstract class ElementProxy {
* @param bytes
*/
public void addBase64Text(byte[] bytes) {
if (bytes != null) {
Text t = XMLUtils.ignoreLineBreaks()
? this._doc.createTextNode(Base64.encode(bytes))
......@@ -338,7 +322,6 @@ public abstract class ElementProxy {
* @param text
*/
public void addText(String text) {
if (text != null) {
Text t = this._doc.createTextNode(text);
......@@ -351,16 +334,17 @@ public abstract class ElementProxy {
*
* @param localname
* @param namespace
* @return The biginter contained in the given element
* @return The biginteger contained in the given element
* @throws Base64DecodingException
*/
public BigInteger getBigIntegerFromChildElement(
String localname, String namespace) throws Base64DecodingException {
String localname, String namespace
) throws Base64DecodingException {
return Base64.decodeBigIntegerFromText(
XMLUtils.selectNodeText(this._constructionElement.getFirstChild(),
namespace,localname,0));
XMLUtils.selectNodeText(
this._constructionElement.getFirstChild(), namespace, localname, 0
)
);
}
/**
......@@ -374,13 +358,10 @@ public abstract class ElementProxy {
@Deprecated
public byte[] getBytesFromChildElement(String localname, String namespace)
throws XMLSecurityException {
Element e =
XMLUtils.selectNode(
this._constructionElement.getFirstChild(),
namespace,
localname,
0);
this._constructionElement.getFirstChild(), namespace, localname, 0
);
return Base64.decode(e);
}
......@@ -393,13 +374,11 @@ public abstract class ElementProxy {
* @return the Text of the textNode
*/
public String getTextFromChildElement(String localname, String namespace) {
return XMLUtils.selectNode(
this._constructionElement.getFirstChild(),
namespace,
localname,
0).getFirstChild().getNodeValue();
0).getTextContent();
}
/**
......@@ -409,8 +388,7 @@ public abstract class ElementProxy {
* @throws XMLSecurityException
*/
public byte[] getBytesFromTextChild() throws XMLSecurityException {
return Base64.decode
(XMLUtils.getFullTextChildrenFromElement(this._constructionElement));
return Base64.decode(XMLUtils.getFullTextChildrenFromElement(this._constructionElement));
}
/**
......@@ -431,15 +409,14 @@ public abstract class ElementProxy {
* @return the number of elements {namespace}:localname under this element
*/
public int length(String namespace, String localname) {
int number=0;
Node sibling=this._constructionElement.getFirstChild();
while (sibling!=null) {
int number = 0;
Node sibling = this._constructionElement.getFirstChild();
while (sibling != null) {
if (localname.equals(sibling.getLocalName())
&&
namespace==sibling.getNamespaceURI() ) {
&& namespace.equals(sibling.getNamespaceURI())) {
number++;
}
sibling=sibling.getNextSibling();
sibling = sibling.getNextSibling();
}
return number;
}
......@@ -459,7 +436,6 @@ public abstract class ElementProxy {
*/
public void setXPathNamespaceContext(String prefix, String uri)
throws XMLSecurityException {
String ns;
if ((prefix == null) || (prefix.length() == 0)) {
......@@ -472,30 +448,20 @@ public abstract class ElementProxy {
ns = "xmlns:" + prefix;
}
Attr a = this._constructionElement.getAttributeNodeNS(Constants.NamespaceSpecNS, ns);
if (a != null) {
if (!a.getNodeValue().equals(uri)) {
Object exArgs[] = { ns,
this._constructionElement.getAttributeNS(null,
ns) };
Object exArgs[] = { ns, this._constructionElement.getAttributeNS(null, ns) };
throw new XMLSecurityException("namespacePrefixAlreadyUsedByOtherURI",
exArgs);
throw new XMLSecurityException("namespacePrefixAlreadyUsedByOtherURI", exArgs);
}
return;
}
this._constructionElement.setAttributeNS(Constants.NamespaceSpecNS, ns,
uri);
this._constructionElement.setAttributeNS(Constants.NamespaceSpecNS, ns, uri);
}
/** Field _prefixMappings */
static Map<String, String> _prefixMappings = new HashMap<String,String>();
static Map<String, String> _prefixMappingsBindings = new HashMap<String,String>();
/**
* Method setDefaultPrefix
*
......@@ -505,25 +471,38 @@ public abstract class ElementProxy {
*/
public static void setDefaultPrefix(String namespace, String prefix)
throws XMLSecurityException {
if (ElementProxy._prefixMappings.containsValue(prefix)) {
Object storedNamespace=ElementProxy._prefixMappings.get(namespace);
if (!storedNamespace.equals(prefix)) {
Object exArgs[] = { prefix, namespace, storedNamespace };
if (prefixMappings.containsValue(prefix)) {
String storedPrefix = prefixMappings.get(namespace);
if (!storedPrefix.equals(prefix)) {
Object exArgs[] = { prefix, namespace, storedPrefix };
throw new XMLSecurityException("prefix.AlreadyAssigned", exArgs);
}
}
if (Constants.SignatureSpecNS.equals(namespace)) {
XMLUtils.dsPrefix=prefix;
XMLUtils.setDsPrefix(prefix);
}
ElementProxy._prefixMappings.put(namespace, prefix.intern());
if (prefix.length() == 0) {
ElementProxy._prefixMappingsBindings.put(namespace, "xmlns");
} else {
ElementProxy._prefixMappingsBindings.put(namespace, ("xmlns:"+prefix).intern());
if (EncryptionConstants.EncryptionSpecNS.equals(namespace)) {
XMLUtils.setXencPrefix(prefix);
}
prefixMappings.put(namespace, prefix);
}
/**
* This method registers the default prefixes.
*/
public static void registerDefaultPrefixes() throws XMLSecurityException {
setDefaultPrefix("http://www.w3.org/2000/09/xmldsig#", "ds");
setDefaultPrefix("http://www.w3.org/2001/04/xmlenc#", "xenc");
setDefaultPrefix("http://www.w3.org/2009/xmlenc11#", "xenc11");
setDefaultPrefix("http://www.xmlsecurity.org/experimental#", "experimental");
setDefaultPrefix("http://www.w3.org/2002/04/xmldsig-filter2", "dsig-xpath-old");
setDefaultPrefix("http://www.w3.org/2002/06/xmldsig-filter2", "dsig-xpath");
setDefaultPrefix("http://www.w3.org/2001/10/xml-exc-c14n#", "ec");
setDefaultPrefix(
"http://www.nue.et-inf.uni-siegen.de/~geuer-pollmann/#xpathFilter", "xx"
);
}
/**
......@@ -533,10 +512,7 @@ public abstract class ElementProxy {
* @return the default prefix bind to this element.
*/
public static String getDefaultPrefix(String namespace) {
return ElementProxy._prefixMappings.get(namespace);
return prefixMappings.get(namespace);
}
public static String getDefaultPrefixBindings(String namespace) {
return ElementProxy._prefixMappingsBindings.get(namespace);
}
}
......@@ -2,21 +2,23 @@
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.sun.org.apache.xml.internal.security.utils;
......@@ -37,32 +39,17 @@ public class I18n {
+ "Call the static method \"com.sun.org.apache.xml.internal.security.Init.init();\" to do that "
+ "before you use any functionality from that library.";
/** Field defaultLanguageCode */
private static String defaultLanguageCode; // will be set in static{} block
/** Field defaultCountryCode */
private static String defaultCountryCode; // will be set in static{} block
/** Field resourceBundle */
private static ResourceBundle resourceBundle =
ResourceBundle.getBundle
(Constants.exceptionMessagesResourceBundleBase, Locale.US);
private static ResourceBundle resourceBundle;
/** Field alreadyInitialized */
private static boolean alreadyInitialized = false;
/** Field _languageCode */
private static String _languageCode = null;
/** Field _countryCode */
private static String _countryCode = null;
/**
* Constructor I18n
*
*/
private I18n() {
// we don't allow instantiation
}
......@@ -75,7 +62,8 @@ public class I18n {
* <CODE>exceptionMessagesResourceBundleBase</CODE>
*
* @param message
* @param args is an <CODE>Object[]</CODE> array of strings which are inserted into the String which is retrieved from the <CODE>ResouceBundle</CODE>
* @param args is an <CODE>Object[]</CODE> array of strings which are inserted into
* the String which is retrieved from the <CODE>ResouceBundle</CODE>
* @return message translated
*/
public static String translate(String message, Object[] args) {
......@@ -85,8 +73,8 @@ public class I18n {
/**
* Method translate
*
* translates a message ID into an internationalized String, see alse
* <CODE>XMLSecurityException.getExceptionMEssage()</CODE>
* translates a message ID into an internationalized String, see also
* <CODE>XMLSecurityException.getExceptionMessage()</CODE>
*
* @param message
* @return message translated
......@@ -103,11 +91,8 @@ public class I18n {
*
*/
public static String getExceptionMessage(String msgID) {
try {
String s = resourceBundle.getString(msgID);
return s;
return resourceBundle.getString(msgID);
} catch (Throwable t) {
if (com.sun.org.apache.xml.internal.security.Init.isInitialized()) {
return "No message with ID \"" + msgID
......@@ -125,15 +110,10 @@ public class I18n {
* @param originalException
* @return message translated
*/
public static String getExceptionMessage(String msgID,
Exception originalException) {
public static String getExceptionMessage(String msgID, Exception originalException) {
try {
Object exArgs[] = { originalException.getMessage() };
String s = MessageFormat.format(resourceBundle.getString(msgID),
exArgs);
return s;
return MessageFormat.format(resourceBundle.getString(msgID), exArgs);
} catch (Throwable t) {
if (com.sun.org.apache.xml.internal.security.Init.isInitialized()) {
return "No message with ID \"" + msgID
......@@ -155,12 +135,8 @@ public class I18n {
* @return message translated
*/
public static String getExceptionMessage(String msgID, Object exArgs[]) {
try {
String s = MessageFormat.format(resourceBundle.getString(msgID),
exArgs);
return s;
return MessageFormat.format(resourceBundle.getString(msgID), exArgs);
} catch (Throwable t) {
if (com.sun.org.apache.xml.internal.security.Init.isInitialized()) {
return "No message with ID \"" + msgID
......@@ -171,62 +147,22 @@ public class I18n {
}
}
//
// Commented out because it modifies shared static
// state which could be maliciously called by untrusted code
//
// /**
// * Method init
// *
// * @param _defaultLanguageCode
// * @param _defaultCountryCode
// */
// public static void init(String _defaultLanguageCode,
// String _defaultCountryCode) {
//
// I18n.defaultLanguageCode = _defaultLanguageCode;
//
// if (I18n.defaultLanguageCode == null) {
// I18n.defaultLanguageCode = Locale.getDefault().getLanguage();
// }
//
// I18n.defaultCountryCode = _defaultCountryCode;
//
// if (I18n.defaultCountryCode == null) {
// I18n.defaultCountryCode = Locale.getDefault().getCountry();
// }
//
// initLocale(I18n.defaultLanguageCode, I18n.defaultCountryCode);
// }
/**
* Method init
*
* @param languageCode
* @param countryCode
*/
public synchronized static void init(String languageCode, String countryCode) {
if (alreadyInitialized) {
return;
}
//
// Commented out because it modifies shared static
// state which could be maliciously called by untrusted code
//
// /**
// * Method initLocale
// *
// * @param languageCode
// * @param countryCode
// */
// public static void initLocale(String languageCode, String countryCode) {
//
// if (alreadyInitialized && languageCode.equals(_languageCode)
// && countryCode.equals(_countryCode)) {
// return;
// }
//
// if ((languageCode != null) && (countryCode != null)
// && (languageCode.length() > 0) && (countryCode.length() > 0)) {
// _languageCode = languageCode;
// _countryCode = countryCode;
// } else {
// _countryCode = I18n.defaultCountryCode;
// _languageCode = I18n.defaultLanguageCode;
// }
//
// I18n.resourceBundle =
// ResourceBundle.getBundle(Constants.exceptionMessagesResourceBundleBase,
// new Locale(_languageCode, _countryCode));
// }
I18n.resourceBundle =
ResourceBundle.getBundle(
Constants.exceptionMessagesResourceBundleBase,
new Locale(languageCode, countryCode)
);
alreadyInitialized = true;
}
}
......@@ -21,14 +21,15 @@
package com.sun.org.apache.xml.internal.security.utils;
import java.io.IOException;
import java.io.OutputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
......@@ -60,6 +61,12 @@ public class XMLUtils {
}
});
private static volatile String dsPrefix = "ds";
private static volatile String xencPrefix = "xenc";
private static final java.util.logging.Logger log =
java.util.logging.Logger.getLogger(XMLUtils.class.getName());
/**
* Constructor XMLUtils
*
......@@ -68,6 +75,23 @@ public class XMLUtils {
// we don't allow instantiation
}
/**
* Set the prefix for the digital signature namespace
* @param prefix the new prefix for the digital signature namespace
*/
public static void setDsPrefix(String prefix) {
dsPrefix = prefix;
}
/**
* Set the prefix for the encryption namespace
* @param prefix the new prefix for the encryption namespace
*/
public static void setXencPrefix(String prefix) {
xencPrefix = prefix;
}
public static Element getNextElement(Node el) {
while ((el!=null) && (el.getNodeType()!=Node.ELEMENT_NODE)) {
el=el.getNextSibling();
......@@ -230,9 +254,8 @@ public class XMLUtils {
return sb.toString();
}
static String dsPrefix=null;
static Map<String, String> namePrefixes=new HashMap<String, String>();
/**
* Creates an Element in the XML Signature specification namespace.
*
......@@ -269,9 +292,13 @@ public class XMLUtils {
* @param localName
* @return true if the element is in XML Signature namespace and the local name equals the supplied one
*/
public static boolean elementIsInSignatureSpace(Element element,
String localName) {
return ElementProxy.checker.isNamespaceElement(element, localName, Constants.SignatureSpecNS);
public static boolean elementIsInSignatureSpace(Element element, String localName) {
if (element == null) {
return false;
}
return Constants.SignatureSpecNS.equals(element.getNamespaceURI())
&& element.getLocalName().equals(localName);
}
/**
......@@ -282,9 +309,12 @@ public class XMLUtils {
* @param localName
* @return true if the element is in XML Encryption namespace and the local name equals the supplied one
*/
public static boolean elementIsInEncryptionSpace(Element element,
String localName) {
return ElementProxy.checker.isNamespaceElement(element, localName, EncryptionConstants.EncryptionSpecNS);
public static boolean elementIsInEncryptionSpace(Element element, String localName) {
if (element == null) {
return false;
}
return EncryptionConstants.EncryptionSpecNS.equals(element.getNamespaceURI())
&& element.getLocalName().equals(localName);
}
/**
......@@ -511,14 +541,15 @@ public class XMLUtils {
* @return nodes with the constrain
*/
public static Element selectDsNode(Node sibling, String nodeName, int number) {
while (sibling!=null) {
if (ElementProxy.checker.isNamespaceElement(sibling, nodeName, Constants.SignatureSpecNS )) {
if (number==0){
while (sibling != null) {
if (Constants.SignatureSpecNS.equals(sibling.getNamespaceURI())
&& sibling.getLocalName().equals(nodeName)) {
if (number == 0){
return (Element)sibling;
}
number--;
}
sibling=sibling.getNextSibling();
sibling = sibling.getNextSibling();
}
return null;
}
......@@ -529,21 +560,20 @@ public class XMLUtils {
* @param number
* @return nodes with the constrain
*/
public static Element selectXencNode(Node sibling, String nodeName, int number) {
while (sibling!=null) {
if (ElementProxy.checker.isNamespaceElement(sibling, nodeName, EncryptionConstants.EncryptionSpecNS )) {
if (number==0){
while (sibling != null) {
if (EncryptionConstants.EncryptionSpecNS.equals(sibling.getNamespaceURI())
&& sibling.getLocalName().equals(nodeName)) {
if (number == 0){
return (Element)sibling;
}
number--;
}
sibling=sibling.getNextSibling();
sibling = sibling.getNextSibling();
}
return null;
}
/**
* @param sibling
* @param nodeName
......@@ -588,15 +618,16 @@ public class XMLUtils {
* @param number
* @return nodes with the constrain
*/
public static Element selectNode(Node sibling, String uri,String nodeName, int number) {
while (sibling!=null) {
if (ElementProxy.checker.isNamespaceElement(sibling, nodeName, uri)) {
if (number==0){
public static Element selectNode(Node sibling, String uri, String nodeName, int number) {
while (sibling != null) {
if (sibling.getNamespaceURI() != null && sibling.getNamespaceURI().equals(uri)
&& sibling.getLocalName().equals(nodeName)) {
if (number == 0){
return (Element)sibling;
}
number--;
}
sibling=sibling.getNextSibling();
sibling = sibling.getNextSibling();
}
return null;
}
......@@ -606,36 +637,26 @@ public class XMLUtils {
* @param nodeName
* @return nodes with the constrain
*/
public static Element[] selectDsNodes(Node sibling,String nodeName) {
return selectNodes(sibling,Constants.SignatureSpecNS,nodeName);
public static Element[] selectDsNodes(Node sibling, String nodeName) {
return selectNodes(sibling,Constants.SignatureSpecNS, nodeName);
}
/**
* @param sibling
* @param uri
* @param nodeName
* @return nodes with the constrain
*/
public static Element[] selectNodes(Node sibling,String uri,String nodeName) {
int size=20;
Element[] a= new Element[size];
int curr=0;
//List list=new ArrayList();
while (sibling!=null) {
if (ElementProxy.checker.isNamespaceElement(sibling, nodeName, uri)) {
a[curr++]=(Element)sibling;
if (size<=curr) {
int cursize= size<<2;
Element []cp=new Element[cursize];
System.arraycopy(a,0,cp,0,size);
a=cp;
size=cursize;
public static Element[] selectNodes(Node sibling, String uri, String nodeName) {
List<Element> list = new ArrayList<Element>();
while (sibling != null) {
if (sibling.getNamespaceURI() != null && sibling.getNamespaceURI().equals(uri)
&& sibling.getLocalName().equals(nodeName)) {
list.add((Element)sibling);
}
sibling = sibling.getNextSibling();
}
sibling=sibling.getNextSibling();
}
Element []af=new Element[curr];
System.arraycopy(a,0,af,0,curr);
return af;
return list.toArray(new Element[list.size()]);
}
/**
......@@ -694,4 +715,127 @@ public class XMLUtils {
public static boolean ignoreLineBreaks() {
return ignoreLineBreaks;
}
/**
* This method is a tree-search to help prevent against wrapping attacks.
* It checks that no two Elements have ID Attributes that match the "value"
* argument, if this is the case then "false" is returned. Note that a
* return value of "true" does not necessarily mean that a matching Element
* has been found, just that no wrapping attack has been detected.
*/
public static boolean protectAgainstWrappingAttack(Node startNode,
String value)
{
Node startParent = startNode.getParentNode();
Node processedNode = null;
Element foundElement = null;
String id = value.trim();
if (id.charAt(0) == '#') {
id = id.substring(1);
}
while (startNode != null) {
if (startNode.getNodeType() == Node.ELEMENT_NODE) {
Element se = (Element) startNode;
NamedNodeMap attributes = se.getAttributes();
if (attributes != null) {
for (int i = 0; i < attributes.getLength(); i++) {
Attr attr = (Attr)attributes.item(i);
if (attr.isId() && id.equals(attr.getValue())) {
if (foundElement == null) {
// Continue searching to find duplicates
foundElement = attr.getOwnerElement();
} else {
log.log(java.util.logging.Level.FINE, "Multiple elements with the same 'Id' attribute value!");
return false;
}
}
}
}
}
processedNode = startNode;
startNode = startNode.getFirstChild();
// no child, this node is done.
if (startNode == null) {
// close node processing, get sibling
startNode = processedNode.getNextSibling();
}
// no more siblings, get parent, all children
// of parent are processed.
while (startNode == null) {
processedNode = processedNode.getParentNode();
if (processedNode == startParent) {
return true;
}
// close parent node processing (processed node now)
startNode = processedNode.getNextSibling();
}
}
return true;
}
/**
* This method is a tree-search to help prevent against wrapping attacks.
* It checks that no other Element than the given "knownElement" argument
* has an ID attribute that matches the "value" argument, which is the ID
* value of "knownElement". If this is the case then "false" is returned.
*/
public static boolean protectAgainstWrappingAttack(Node startNode,
Element knownElement,
String value)
{
Node startParent = startNode.getParentNode();
Node processedNode = null;
String id = value.trim();
if (id.charAt(0) == '#') {
id = id.substring(1);
}
while (startNode != null) {
if (startNode.getNodeType() == Node.ELEMENT_NODE) {
Element se = (Element) startNode;
NamedNodeMap attributes = se.getAttributes();
if (attributes != null) {
for (int i = 0; i < attributes.getLength(); i++) {
Attr attr = (Attr)attributes.item(i);
if (attr.isId() && id.equals(attr.getValue())
&& se != knownElement)
{
log.log(java.util.logging.Level.FINE, "Multiple elements with the same 'Id' attribute value!");
return false;
}
}
}
}
processedNode = startNode;
startNode = startNode.getFirstChild();
// no child, this node is done.
if (startNode == null) {
// close node processing, get sibling
startNode = processedNode.getNextSibling();
}
// no more siblings, get parent, all children
// of parent are processed.
while (startNode == null) {
processedNode = processedNode.getParentNode();
if (processedNode == startParent) {
return true;
}
// close parent node processing (processed node now)
startNode = processedNode.getNextSibling();
}
}
return true;
}
}
......@@ -2,21 +2,23 @@
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.sun.org.apache.xml.internal.security.utils.resolver;
......@@ -25,253 +27,260 @@ 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.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;
import com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverXPointer;
import org.w3c.dom.Attr;
/**
* During reference validation, we have to retrieve resources from somewhere.
* This is done by retrieving a Resolver. The resolver needs two arguments: The
* URI in which the link to the new resource is defined and the BaseURI of the
* file/entity in which the URI occurs (the BaseURI is the same as the SystemId.
*
* <UL xml:lang="DE" LANG="DE">
* <LI> Verschiedene Implementierungen k??nnen sich als Resolver registrieren.
* <LI> Standardm????ig werden erste Implementierungen auf dem XML config file registrirt.
* <LI> Der Benutzer kann bei Bedarf Implementierungen voranstellen oder anf??gen.
* <LI> Implementierungen k??nnen mittels Features customized werden ??
* (z.B. um Proxy-Passworter ??bergeben zu k??nnen).
* <LI> Jede Implementierung bekommt das URI Attribut und den Base URI
* ??bergeben und muss antworten, ob sie aufl??sen kann.
* <LI> Die erste Implementierung, die die Aufgabe erf??llt, f??hrt die Aufl??sung durch.
* </UL>
*
* @author $Author: mullan $
* URI in which the link to the new resource is defined and the baseURI of the
* file/entity in which the URI occurs (the baseURI is the same as the SystemId).
*/
public class ResourceResolver {
/** {@link java.util.logging} logging facility */
static java.util.logging.Logger log =
/** {@link org.apache.commons.logging} logging facility */
private static java.util.logging.Logger log =
java.util.logging.Logger.getLogger(ResourceResolver.class.getName());
/** Field _alreadyInitialized */
static boolean _alreadyInitialized = false;
/** these are the system-wide resolvers */
static List<ResourceResolver> _resolverVector = null;
static boolean allThreadSafeInList=true;
private static List<ResourceResolver> resolverList = new ArrayList<ResourceResolver>();
/** Field transformSpi */
protected ResourceResolverSpi _resolverSpi = null;
/** Field resolverSpi */
private final ResourceResolverSpi resolverSpi;
/**
* Constructor ResourceResolver
*
* @param className
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
* @param resourceResolver
*/
private ResourceResolver(String className)
throws ClassNotFoundException, IllegalAccessException,
InstantiationException {
this._resolverSpi =
(ResourceResolverSpi) Class.forName(className).newInstance();
public ResourceResolver(ResourceResolverSpi resourceResolver) {
this.resolverSpi = resourceResolver;
}
/**
* Constructor ResourceResolver
* Method getInstance
*
* @param resourceResolver
* @param uri
* @param baseURI
* @return the instance
*
* @throws ResourceResolverException
*/
public ResourceResolver(ResourceResolverSpi resourceResolver) {
this._resolverSpi = resourceResolver;
public static final ResourceResolver getInstance(Attr uri, String baseURI)
throws ResourceResolverException {
return getInstance(uri, baseURI, false);
}
/**
* Method getInstance
*
* @param uri
* @param BaseURI
* @return the instnace
* @param baseURI
* @param secureValidation
* @return the instance
*
* @throws ResourceResolverException
*/
public static final ResourceResolver getInstance(Attr uri, String BaseURI)
throws ResourceResolverException {
int length=ResourceResolver._resolverVector.size();
for (int i = 0; i < length; i++) {
ResourceResolver resolver =
ResourceResolver._resolverVector.get(i);
ResourceResolver resolverTmp=null;
public static final ResourceResolver getInstance(
Attr uri, String baseURI, boolean secureValidation
) throws ResourceResolverException {
synchronized (resolverList) {
for (ResourceResolver resolver : resolverList) {
ResourceResolver resolverTmp = resolver;
if (!resolver.resolverSpi.engineIsThreadSafe()) {
try {
resolverTmp = allThreadSafeInList || resolver._resolverSpi.engineIsThreadSafe() ? resolver :
new ResourceResolver((ResourceResolverSpi)resolver._resolverSpi.getClass().newInstance());
resolverTmp =
new ResourceResolver(resolver.resolverSpi.getClass().newInstance());
} catch (InstantiationException e) {
throw new ResourceResolverException("",e,uri,BaseURI);
throw new ResourceResolverException("", e, uri, baseURI);
} catch (IllegalAccessException e) {
throw new ResourceResolverException("",e,uri,BaseURI);
throw new ResourceResolverException("", e, uri, baseURI);
}
}
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "check resolvability by class " + resolver._resolverSpi.getClass().getName());
if ((resolver != null) && resolverTmp.canResolve(uri, BaseURI)) {
if (i!=0) {
//update resolver.
//System.out.println("Swaping");
List<ResourceResolver> resolverVector=getResolverVectorClone();
resolverVector.remove(i);
resolverVector.add(0,resolver);
_resolverVector=resolverVector;
} else {
//System.out.println("hitting");
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE,
"check resolvability by class " + resolverTmp.getClass().getName()
);
}
resolverTmp.resolverSpi.secureValidation = secureValidation;
if ((resolverTmp != null) && resolverTmp.canResolve(uri, baseURI)) {
// Check to see whether the Resolver is allowed
if (secureValidation
&& (resolverTmp.resolverSpi instanceof ResolverLocalFilesystem
|| resolverTmp.resolverSpi instanceof ResolverDirectHTTP)) {
Object exArgs[] = { resolverTmp.resolverSpi.getClass().getName() };
throw new ResourceResolverException(
"signature.Reference.ForbiddenResolver", exArgs, uri, baseURI
);
}
return resolverTmp;
}
}
}
Object exArgs[] = { ((uri != null)
? uri.getNodeValue()
: "null"), BaseURI };
Object exArgs[] = { ((uri != null) ? uri.getNodeValue() : "null"), baseURI };
throw new ResourceResolverException("utils.resolver.noClass", exArgs,
uri, BaseURI);
throw new ResourceResolverException("utils.resolver.noClass", exArgs, uri, baseURI);
}
/**
* Method getResolverVectorClone
* Method getInstance
*
* @return clone of _resolverVector
* @param uri
* @param baseURI
* @param individualResolvers
* @return the instance
*
* @throws ResourceResolverException
*/
@SuppressWarnings("unchecked")
private static List<ResourceResolver> getResolverVectorClone() {
return (List<ResourceResolver>)((ArrayList<ResourceResolver>)_resolverVector).clone();
public static ResourceResolver getInstance(
Attr uri, String baseURI, List<ResourceResolver> individualResolvers
) throws ResourceResolverException {
return getInstance(uri, baseURI, individualResolvers, false);
}
/**
* Method getInstance
*
* @param uri
* @param BaseURI
* @param baseURI
* @param individualResolvers
* @param secureValidation
* @return the instance
*
* @throws ResourceResolverException
*/
public static final ResourceResolver getInstance(
Attr uri, String BaseURI, List<ResourceResolver> individualResolvers)
throws ResourceResolverException {
public static ResourceResolver getInstance(
Attr uri, String baseURI, List<ResourceResolver> individualResolvers, boolean secureValidation
) throws ResourceResolverException {
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "I was asked to create a ResourceResolver and got " + (individualResolvers==null? 0 : individualResolvers.size()) );
log.log(java.util.logging.Level.FINE, " extra resolvers to my existing " + ResourceResolver._resolverVector.size() + " system-wide resolvers");
log.log(java.util.logging.Level.FINE,
"I was asked to create a ResourceResolver and got "
+ (individualResolvers == null ? 0 : individualResolvers.size())
);
}
// first check the individual Resolvers
int size=0;
if ((individualResolvers != null) && ((size=individualResolvers.size()) > 0)) {
for (int i = 0; i < size; i++) {
ResourceResolver resolver =
individualResolvers.get(i);
if (individualResolvers != null) {
for (int i = 0; i < individualResolvers.size(); i++) {
ResourceResolver resolver = individualResolvers.get(i);
if (resolver != null) {
String currentClass = resolver._resolverSpi.getClass().getName();
if (log.isLoggable(java.util.logging.Level.FINE))
if (log.isLoggable(java.util.logging.Level.FINE)) {
String currentClass = resolver.resolverSpi.getClass().getName();
log.log(java.util.logging.Level.FINE, "check resolvability by class " + currentClass);
}
if (resolver.canResolve(uri, BaseURI)) {
resolver.resolverSpi.secureValidation = secureValidation;
if (resolver.canResolve(uri, baseURI)) {
return resolver;
}
}
}
}
return getInstance(uri,BaseURI);
}
/**
* The init() function is called by com.sun.org.apache.xml.internal.security.Init.init()
*/
public static void init() {
if (!ResourceResolver._alreadyInitialized) {
ResourceResolver._resolverVector = new ArrayList<ResourceResolver>(10);
_alreadyInitialized = true;
}
return getInstance(uri, baseURI, secureValidation);
}
/**
* Registers a ResourceResolverSpi class. This method logs a warning if
* the class cannot be registered.
*
* @param className the name of the ResourceResolverSpi class to be
* registered
* @param className the name of the ResourceResolverSpi class to be registered
*/
@SuppressWarnings("unchecked")
public static void register(String className) {
register(className, false);
try {
Class<ResourceResolverSpi> resourceResolverClass =
(Class<ResourceResolverSpi>) Class.forName(className);
register(resourceResolverClass, false);
} catch (ClassNotFoundException e) {
log.log(java.util.logging.Level.WARNING, "Error loading resolver " + className + " disabling it");
}
}
/**
* Registers a ResourceResolverSpi class at the beginning of the provider
* list. This method logs a warning if the class cannot be registered.
*
* @param className the name of the ResourceResolverSpi class to be
* registered
* @param className the name of the ResourceResolverSpi class to be registered
*/
@SuppressWarnings("unchecked")
public static void registerAtStart(String className) {
register(className, true);
try {
Class<ResourceResolverSpi> resourceResolverClass =
(Class<ResourceResolverSpi>) Class.forName(className);
register(resourceResolverClass, true);
} catch (ClassNotFoundException e) {
log.log(java.util.logging.Level.WARNING, "Error loading resolver " + className + " disabling it");
}
}
private static void register(String className, boolean start) {
/**
* Registers a ResourceResolverSpi class. This method logs a warning if the class
* cannot be registered.
* @param className
* @param start
*/
public static void register(Class<? extends ResourceResolverSpi> className, boolean start) {
try {
ResourceResolver resolver = new ResourceResolver(className);
ResourceResolverSpi resourceResolverSpi = className.newInstance();
register(resourceResolverSpi, start);
} catch (IllegalAccessException e) {
log.log(java.util.logging.Level.WARNING, "Error loading resolver " + className + " disabling it");
} catch (InstantiationException e) {
log.log(java.util.logging.Level.WARNING, "Error loading resolver " + className + " disabling it");
}
}
/**
* Registers a ResourceResolverSpi instance. This method logs a warning if the class
* cannot be registered.
* @param resourceResolverSpi
* @param start
*/
public static void register(ResourceResolverSpi resourceResolverSpi, boolean start) {
synchronized(resolverList) {
if (start) {
ResourceResolver._resolverVector.add(0, resolver);
log.log(java.util.logging.Level.FINE, "registered resolver");
resolverList.add(0, new ResourceResolver(resourceResolverSpi));
} else {
ResourceResolver._resolverVector.add(resolver);
resolverList.add(new ResourceResolver(resourceResolverSpi));
}
if (!resolver._resolverSpi.engineIsThreadSafe()) {
allThreadSafeInList=false;
}
} catch (Exception e) {
log.log(java.util.logging.Level.WARNING, "Error loading resolver " + className +" disabling it");
} catch (NoClassDefFoundError e) {
log.log(java.util.logging.Level.WARNING, "Error loading resolver " + className +" disabling it");
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Registered resolver: " + resourceResolverSpi.toString());
}
}
/**
* Method resolve
*
* @param uri
* @param BaseURI
* @return the resource
*
* @throws ResourceResolverException
* This method registers the default resolvers.
*/
public static XMLSignatureInput resolveStatic(Attr uri, String BaseURI)
throws ResourceResolverException {
ResourceResolver myResolver = ResourceResolver.getInstance(uri, BaseURI);
return myResolver.resolve(uri, BaseURI);
public static void registerDefaultResolvers() {
synchronized(resolverList) {
resolverList.add(new ResourceResolver(new ResolverFragment()));
resolverList.add(new ResourceResolver(new ResolverLocalFilesystem()));
resolverList.add(new ResourceResolver(new ResolverXPointer()));
resolverList.add(new ResourceResolver(new ResolverDirectHTTP()));
}
}
/**
* Method resolve
*
* @param uri
* @param BaseURI
* @param baseURI
* @return the resource
*
* @throws ResourceResolverException
*/
public XMLSignatureInput resolve(Attr uri, String BaseURI)
public XMLSignatureInput resolve(Attr uri, String baseURI)
throws ResourceResolverException {
return this._resolverSpi.engineResolve(uri, BaseURI);
return resolverSpi.engineResolve(uri, baseURI);
}
/**
......@@ -281,7 +290,7 @@ public class ResourceResolver {
* @param value
*/
public void setProperty(String key, String value) {
this._resolverSpi.engineSetProperty(key, value);
resolverSpi.engineSetProperty(key, value);
}
/**
......@@ -291,7 +300,7 @@ public class ResourceResolver {
* @return the value of the property
*/
public String getProperty(String key) {
return this._resolverSpi.engineGetProperty(key);
return resolverSpi.engineGetProperty(key);
}
/**
......@@ -299,8 +308,8 @@ public class ResourceResolver {
*
* @param properties
*/
public void addProperties(Map<String,String> properties) {
this._resolverSpi.engineAddProperies(properties);
public void addProperties(Map<String, String> properties) {
resolverSpi.engineAddProperies(properties);
}
/**
......@@ -309,7 +318,7 @@ public class ResourceResolver {
* @return all property keys.
*/
public String[] getPropertyKeys() {
return this._resolverSpi.engineGetPropertyKeys();
return resolverSpi.engineGetPropertyKeys();
}
/**
......@@ -319,17 +328,17 @@ public class ResourceResolver {
* @return true if the resolver understands the property
*/
public boolean understandsProperty(String propertyToTest) {
return this._resolverSpi.understandsProperty(propertyToTest);
return resolverSpi.understandsProperty(propertyToTest);
}
/**
* Method canResolve
*
* @param uri
* @param BaseURI
* @param baseURI
* @return true if it can resolve the uri
*/
private boolean canResolve(Attr uri, String BaseURI) {
return this._resolverSpi.engineCanResolve(uri, BaseURI);
private boolean canResolve(Attr uri, String baseURI) {
return resolverSpi.engineCanResolve(uri, baseURI);
}
}
......@@ -43,6 +43,8 @@ public abstract class ResourceResolverSpi {
/** Field _properties */
protected java.util.Map<String,String> _properties = null;
protected boolean secureValidation;
/**
* This is the workhorse method used to resolve resources.
*
......
......@@ -23,11 +23,12 @@ package com.sun.org.apache.xml.internal.security.utils.resolver.implementations;
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
import com.sun.org.apache.xml.internal.security.utils.IdResolver;
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException;
import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverSpi;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
......@@ -51,21 +52,16 @@ public class ResolverFragment extends ResourceResolverSpi {
/**
* Method engineResolve
*
* Wird das gleiche Dokument referenziert?
* Wird ein anderes Dokument referenziert?
* @inheritDoc
* @param uri
* @param BaseURI
*
* @param baseURI
*/
public XMLSignatureInput engineResolve(Attr uri, String BaseURI)
public XMLSignatureInput engineResolve(Attr uri, String baseURI)
throws ResourceResolverException
{
String uriNodeValue = uri.getNodeValue();
Document doc = uri.getOwnerElement().getOwnerDocument();
Node selectedElem = null;
if (uriNodeValue.equals("")) {
......@@ -88,12 +84,20 @@ public class ResolverFragment extends ResourceResolverSpi {
*/
String id = uriNodeValue.substring(1);
// Element selectedElem = doc.getElementById(id);
selectedElem = IdResolver.getElementById(doc, id);
if (selectedElem==null) {
selectedElem = doc.getElementById(id);
if (selectedElem == null) {
Object exArgs[] = { id };
throw new ResourceResolverException(
"signature.Verification.MissingID", exArgs, uri, baseURI);
}
if (secureValidation) {
Element start = uri.getOwnerDocument().getDocumentElement();
if (!XMLUtils.protectAgainstWrappingAttack(start, id)) {
Object exArgs[] = { id };
throw new ResourceResolverException(
"signature.Verification.MissingID", exArgs, uri, BaseURI);
"signature.Verification.MultipleIDs", exArgs,
uri, baseURI);
}
}
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "Try to catch an Element with ID " + id + " and Element was " + selectedElem);
......@@ -102,10 +106,12 @@ public class ResolverFragment extends ResourceResolverSpi {
XMLSignatureInput result = new XMLSignatureInput(selectedElem);
result.setExcludeComments(true);
//log.log(java.util.logging.Level.FINE, "We return a nodeset with " + resultSet.size() + " nodes");
result.setMIMEType("text/xml");
result.setSourceURI((BaseURI != null) ? BaseURI.concat(uri.getNodeValue()) :
uri.getNodeValue());
if (baseURI != null && baseURI.length() > 0) {
result.setSourceURI(baseURI.concat(uri.getNodeValue()));
} else {
result.setSourceURI(uri.getNodeValue());
}
return result;
}
......
......@@ -23,11 +23,12 @@ package com.sun.org.apache.xml.internal.security.utils.resolver.implementations;
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
import com.sun.org.apache.xml.internal.security.utils.IdResolver;
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException;
import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverSpi;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
......@@ -56,44 +57,47 @@ public class ResolverXPointer extends ResourceResolverSpi {
public boolean engineIsThreadSafe() {
return true;
}
/**
* @inheritDoc
*/
public XMLSignatureInput engineResolve(Attr uri, String BaseURI)
public XMLSignatureInput engineResolve(Attr uri, String baseURI)
throws ResourceResolverException {
Node resultNode = null;
Document doc = uri.getOwnerElement().getOwnerDocument();
String uriStr=uri.getNodeValue();
String uriStr = uri.getNodeValue();
if (isXPointerSlash(uriStr)) {
resultNode = doc;
} else if (isXPointerId(uriStr)) {
String id = getXPointerId(uriStr);
resultNode =IdResolver.getElementById(doc, id);
resultNode = doc.getElementById(id);
// log.log(java.util.logging.Level.FINE, "Use #xpointer(id('" + id + "')) on element " + selectedElem);
if (secureValidation) {
Element start = uri.getOwnerDocument().getDocumentElement();
if (!XMLUtils.protectAgainstWrappingAttack(start, id)) {
Object exArgs[] = { id };
throw new ResourceResolverException(
"signature.Verification.MultipleIDs", exArgs,
uri, baseURI);
}
}
if (resultNode == null) {
Object exArgs[] = { id };
throw new ResourceResolverException(
"signature.Verification.MissingID", exArgs, uri, BaseURI);
"signature.Verification.MissingID", exArgs, uri, baseURI);
}
/*
resultNodes =
cXPathAPI
.selectNodeList(selectedElem, Canonicalizer
.XPATH_C14N_WITH_COMMENTS_SINGLE_NODE);*/
}
XMLSignatureInput result = new XMLSignatureInput(resultNode);
result.setMIMEType("text/xml");
if (BaseURI != null && BaseURI.length() > 0) {
result.setSourceURI(BaseURI.concat(uri.getNodeValue()));
if (baseURI != null && baseURI.length() > 0) {
result.setSourceURI(baseURI.concat(uri.getNodeValue()));
} else {
result.setSourceURI(uri.getNodeValue());
}
......
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -74,11 +74,7 @@ public class DOMValidateContext extends DOMCryptoContext
if (ks == null) {
throw new NullPointerException("key selector is null");
}
if (node == null) {
throw new NullPointerException("node is null");
}
setKeySelector(ks);
this.node = node;
init(node, ks);
}
/**
......@@ -97,11 +93,20 @@ public class DOMValidateContext extends DOMCryptoContext
if (validatingKey == null) {
throw new NullPointerException("validatingKey is null");
}
init(node, KeySelector.singletonKeySelector(validatingKey));
}
private void init(Node node, KeySelector ks) {
if (node == null) {
throw new NullPointerException("node is null");
}
setKeySelector(KeySelector.singletonKeySelector(validatingKey));
this.node = node;
super.setKeySelector(ks);
if (System.getSecurityManager() != null) {
super.setProperty("org.jcp.xml.dsig.secureValidation",
Boolean.TRUE);
}
}
/**
......
......@@ -193,7 +193,7 @@ public abstract class ApacheCanonicalizer extends TransformService {
if (apacheTransform == null) {
try {
apacheTransform = Transform.getInstance
apacheTransform = new Transform
(ownerDoc, getAlgorithm(), transformElem.getChildNodes());
apacheTransform.setElement(transformElem, xc.getBaseURI());
if (log.isLoggable(Level.FINE)) {
......
......@@ -38,6 +38,7 @@ import org.w3c.dom.NodeList;
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
import com.sun.org.apache.xml.internal.security.transforms.Transform;
import com.sun.org.apache.xml.internal.security.transforms.Transforms;
import javax.xml.crypto.*;
import javax.xml.crypto.dom.DOMCryptoContext;
......@@ -117,7 +118,7 @@ public abstract class ApacheTransform extends TransformService {
if (apacheTransform == null) {
try {
apacheTransform = Transform.getInstance
apacheTransform = new Transform
(ownerDoc, getAlgorithm(), transformElem.getChildNodes());
apacheTransform.setElement(transformElem, xc.getBaseURI());
if (log.isLoggable(Level.FINE)) {
......@@ -130,6 +131,15 @@ public abstract class ApacheTransform extends TransformService {
}
}
if (Utils.secureValidation(xc)) {
String algorithm = getAlgorithm();
if (Transforms.TRANSFORM_XSLT.equals(algorithm)) {
throw new TransformException(
"Transform " + algorithm +
" is forbidden when secure validation is enabled");
}
}
XMLSignatureInput in;
if (data instanceof ApacheData) {
if (log.isLoggable(Level.FINE)) {
......
......@@ -34,6 +34,7 @@ import javax.xml.crypto.dom.*;
import java.security.Provider;
import java.util.*;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
......@@ -87,7 +88,13 @@ public final class DOMKeyInfo extends DOMStructure implements KeyInfo {
public DOMKeyInfo(Element kiElem, XMLCryptoContext context,
Provider provider) throws MarshalException {
// get Id attribute, if specified
id = DOMUtils.getAttributeValue(kiElem, "Id");
Attr attr = kiElem.getAttributeNodeNS(null, "Id");
if (attr != null) {
id = attr.getValue();
kiElem.setIdAttributeNode(attr, true);
} else {
id = null;
}
// get all children nodes
NodeList nl = kiElem.getChildNodes();
......
......@@ -32,6 +32,7 @@ import javax.xml.crypto.dsig.*;
import java.security.Provider;
import java.util.*;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
......@@ -85,12 +86,30 @@ public final class DOMManifest extends DOMStructure implements Manifest {
*/
public DOMManifest(Element manElem, XMLCryptoContext context,
Provider provider) throws MarshalException {
this.id = DOMUtils.getAttributeValue(manElem, "Id");
Attr attr = manElem.getAttributeNodeNS(null, "Id");
if (attr != null) {
this.id = attr.getValue();
manElem.setIdAttributeNode(attr, true);
} else {
this.id = null;
}
boolean secVal = Utils.secureValidation(context);
Element refElem = DOMUtils.getFirstChildElement(manElem);
List refs = new ArrayList();
int refCount = 0;
while (refElem != null) {
refs.add(new DOMReference(refElem, context, provider));
refElem = DOMUtils.getNextSiblingElement(refElem);
refCount++;
if (secVal && (refCount > DOMSignedInfo.MAXIMUM_REFERENCE_COUNT)) {
String error = "A maxiumum of " +
DOMSignedInfo.MAXIMUM_REFERENCE_COUNT +
" references per Manifest are allowed with" +
" secure validation";
throw new MarshalException(error);
}
}
this.references = Collections.unmodifiableList(refs);
}
......
......@@ -51,6 +51,7 @@ import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.jcp.xml.dsig.internal.DigesterOutputStream;
import com.sun.org.apache.xml.internal.security.algorithms.MessageDigestAlgorithm;
import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
import com.sun.org.apache.xml.internal.security.utils.Base64;
......@@ -65,6 +66,12 @@ import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream
public final class DOMReference extends DOMStructure
implements Reference, DOMURIReference {
/**
* The maximum number of transforms per reference, if secure validation
* is enabled.
*/
public static final int MAXIMUM_TRANSFORM_COUNT = 5;
/**
* Look up useC14N11 system property. If true, an explicit C14N11 transform
* will be added if necessary when generating the signature. See section
......@@ -184,15 +191,27 @@ public final class DOMReference extends DOMStructure
*/
public DOMReference(Element refElem, XMLCryptoContext context,
Provider provider) throws MarshalException {
boolean secVal = Utils.secureValidation(context);
// unmarshal Transforms, if specified
Element nextSibling = DOMUtils.getFirstChildElement(refElem);
List transforms = new ArrayList(5);
if (nextSibling.getLocalName().equals("Transforms")) {
Element transformElem = DOMUtils.getFirstChildElement(nextSibling);
int transformCount = 0;
while (transformElem != null) {
transforms.add
(new DOMTransform(transformElem, context, provider));
transformElem = DOMUtils.getNextSiblingElement(transformElem);
transformCount++;
if (secVal && (transformCount > MAXIMUM_TRANSFORM_COUNT)) {
String error = "A maxiumum of " + MAXIMUM_TRANSFORM_COUNT +
" transforms per Reference are allowed" +
" with secure validation";
throw new MarshalException(error);
}
}
nextSibling = DOMUtils.getNextSiblingElement(nextSibling);
}
......@@ -200,6 +219,14 @@ public final class DOMReference extends DOMStructure
// unmarshal DigestMethod
Element dmElem = nextSibling;
this.digestMethod = DOMDigestMethod.unmarshal(dmElem);
String digestMethodAlgorithm = this.digestMethod.getAlgorithm();
if (secVal
&& MessageDigestAlgorithm.ALGO_ID_DIGEST_NOT_RECOMMENDED_MD5.equals(digestMethodAlgorithm))
{
throw new MarshalException("It is forbidden to use algorithm " +
digestMethod +
" when secure validation is enabled");
}
// unmarshal DigestValue
try {
......@@ -211,7 +238,14 @@ public final class DOMReference extends DOMStructure
// unmarshal attributes
this.uri = DOMUtils.getAttributeValue(refElem, "URI");
this.id = DOMUtils.getAttributeValue(refElem, "Id");
Attr attr = refElem.getAttributeNodeNS(null, "Id");
if (attr != null) {
this.id = attr.getValue();
refElem.setIdAttributeNode(attr, true);
} else {
this.id = null;
}
this.type = DOMUtils.getAttributeValue(refElem, "Type");
this.here = refElem.getAttributeNodeNS(null, "URI");
......
......@@ -38,6 +38,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.security.Provider;
import java.util.*;
import javax.xml.XMLConstants;
import javax.xml.crypto.*;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dom.DOMCryptoContext;
......@@ -124,9 +125,13 @@ public final class DOMRetrievalMethod extends DOMStructure
// get here node
here = rmElem.getAttributeNodeNS(null, "URI");
boolean secVal = Utils.secureValidation(context);
// get Transforms, if specified
List transforms = new ArrayList();
Element transformsElem = DOMUtils.getFirstChildElement(rmElem);
int transformCount = 0;
if (transformsElem != null) {
Element transformElem =
DOMUtils.getFirstChildElement(transformsElem);
......@@ -134,6 +139,17 @@ public final class DOMRetrievalMethod extends DOMStructure
transforms.add
(new DOMTransform(transformElem, context, provider));
transformElem = DOMUtils.getNextSiblingElement(transformElem);
transformCount++;
if (secVal &&
(transformCount > DOMReference.MAXIMUM_TRANSFORM_COUNT))
{
String error = "A maxiumum of " +
DOMReference.MAXIMUM_TRANSFORM_COUNT +
" transforms per Reference are allowed" +
" with secure validation";
throw new MarshalException(error);
}
}
}
if (transforms.isEmpty()) {
......@@ -224,6 +240,8 @@ public final class DOMRetrievalMethod extends DOMStructure
ApacheData data = (ApacheData) dereference(context);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,
Boolean.TRUE);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new ByteArrayInputStream
(data.getXMLSignatureInput().getBytes()));
......
......@@ -31,6 +31,7 @@ import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.*;
import java.util.*;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
......@@ -86,7 +87,13 @@ public final class DOMSignatureProperties extends DOMStructure
*/
public DOMSignatureProperties(Element propsElem) throws MarshalException{
// unmarshal attributes
id = DOMUtils.getAttributeValue(propsElem, "Id");
Attr attr = propsElem.getAttributeNodeNS(null, "Id");
if (attr != null) {
id = attr.getValue();
propsElem.setIdAttributeNode(attr, true);
} else {
id = null;
}
NodeList nodes = propsElem.getChildNodes();
int length = nodes.getLength();
......
......@@ -31,6 +31,7 @@ import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.*;
import java.util.*;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
......@@ -94,7 +95,13 @@ public final class DOMSignatureProperty extends DOMStructure
if (target == null) {
throw new MarshalException("target cannot be null");
}
id = DOMUtils.getAttributeValue(propElem, "Id");
Attr attr = propElem.getAttributeNodeNS(null, "Id");
if (attr != null) {
id = attr.getValue();
propElem.setIdAttributeNode(attr, true);
} else {
id = null;
}
NodeList nodes = propElem.getChildNodes();
int length = nodes.getLength();
......
......@@ -45,6 +45,7 @@ import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import com.sun.org.apache.xml.internal.security.utils.Constants;
import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
......@@ -55,7 +56,22 @@ import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
*/
public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
/**
* The maximum number of references per Manifest, if secure validation is
* enabled.
*/
public static final int MAXIMUM_REFERENCE_COUNT = 30;
private static Logger log = Logger.getLogger("org.jcp.xml.dsig.internal.dom");
/** Signature - NOT Recommended RSAwithMD5 */
private static final String ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5 =
Constants.MoreAlgorithmsSpecNS + "rsa-md5";
/** HMAC - NOT Recommended HMAC-MD5 */
private static final String ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5 =
Constants.MoreAlgorithmsSpecNS + "hmac-md5";
private List references;
private CanonicalizationMethod canonicalizationMethod;
private SignatureMethod signatureMethod;
......@@ -143,12 +159,31 @@ public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
Element smElem = DOMUtils.getNextSiblingElement(cmElem);
signatureMethod = DOMSignatureMethod.unmarshal(smElem);
boolean secVal = Utils.secureValidation(context);
String sigMethAlg = signatureMethod.getAlgorithm();
if (secVal && ((ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5.equals(sigMethAlg)
|| ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5.equals(sigMethAlg))))
{
throw new MarshalException("It is forbidden to use algorithm " +
signatureMethod +
" when secure validation is enabled");
}
// unmarshal References
ArrayList refList = new ArrayList(5);
Element refElem = DOMUtils.getNextSiblingElement(smElem);
int refCount = 0;
while (refElem != null) {
refList.add(new DOMReference(refElem, context, provider));
refElem = DOMUtils.getNextSiblingElement(refElem);
refCount++;
if (secVal && (refCount > MAXIMUM_REFERENCE_COUNT)) {
String error = "A maxiumum of " + MAXIMUM_REFERENCE_COUNT +
" references per SignedInfo are allowed with" +
" secure validation";
throw new MarshalException(error);
}
}
references = Collections.unmodifiableList(refList);
}
......
......@@ -31,7 +31,7 @@ import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.sun.org.apache.xml.internal.security.Init;
import com.sun.org.apache.xml.internal.security.utils.IdResolver;
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver;
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
......@@ -68,8 +68,11 @@ public class DOMURIDereferencer implements URIDereferencer {
Attr uriAttr = (Attr) domRef.getHere();
String uri = uriRef.getURI();
DOMCryptoContext dcc = (DOMCryptoContext) context;
String baseURI = context.getBaseURI();
boolean secVal = Utils.secureValidation(context);
// Check if same-document URI and register ID
// Check if same-document URI and already registered on the context
if (uri != null && uri.length() != 0 && uri.charAt(0) == '#') {
String id = uri.substring(1);
......@@ -79,19 +82,38 @@ public class DOMURIDereferencer implements URIDereferencer {
id = id.substring(i1+1, i2);
}
// this is a bit of a hack to check for registered
// IDRefs and manually register them with Apache's IdResolver
// map which includes builtin schema knowledge of DSig/Enc IDs
Node referencedElem = dcc.getElementById(id);
if (referencedElem != null) {
IdResolver.registerElementById((Element) referencedElem, id);
Node refElem = dcc.getElementById(id);
if (refElem != null) {
if (secVal) {
Element start =
refElem.getOwnerDocument().getDocumentElement();
if (!XMLUtils.protectAgainstWrappingAttack(start,
(Element)refElem,
id)) {
String error = "Multiple Elements with the same ID " +
id + " were detected";
throw new URIReferenceException(error);
}
}
XMLSignatureInput result = new XMLSignatureInput(refElem);
if (!uri.substring(1).startsWith("xpointer(id(")) {
result.setExcludeComments(true);
}
result.setMIMEType("text/xml");
if (baseURI != null && baseURI.length() > 0) {
result.setSourceURI(baseURI.concat(uriAttr.getNodeValue()));
} else {
result.setSourceURI(uriAttr.getNodeValue());
}
return new ApacheNodeSetData(result);
}
}
try {
String baseURI = context.getBaseURI();
ResourceResolver apacheResolver =
ResourceResolver.getInstance(uriAttr, baseURI);
ResourceResolver.getInstance(uriAttr, baseURI, secVal);
XMLSignatureInput in = apacheResolver.resolve(uriAttr, baseURI);
if (in.isOctetStream()) {
return new ApacheOctetStreamData(in);
......
......@@ -38,8 +38,6 @@ import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.spec.*;
import com.sun.org.apache.xml.internal.security.utils.IdResolver;
/**
* Useful static DOM utility methods.
*
......@@ -107,7 +105,7 @@ public class DOMUtils {
public static void setAttributeID(Element elem, String name, String value) {
if (value == null) return;
elem.setAttributeNS(null, name, value);
IdResolver.registerElementById(elem, value);
elem.setIdAttributeNS(null, name, true);
}
/**
......
......@@ -32,6 +32,7 @@ import javax.xml.crypto.dsig.*;
import java.security.Provider;
import java.util.*;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
......@@ -91,7 +92,14 @@ public final class DOMXMLObject extends DOMStructure implements XMLObject {
Provider provider) throws MarshalException {
// unmarshal attributes
this.encoding = DOMUtils.getAttributeValue(objElem, "Encoding");
this.id = DOMUtils.getAttributeValue(objElem, "Id");
Attr attr = objElem.getAttributeNodeNS(null, "Id");
if (attr != null) {
this.id = attr.getValue();
objElem.setIdAttributeNode(attr, true);
} else {
this.id = null;
}
this.mimeType = DOMUtils.getAttributeValue(objElem, "MimeType");
NodeList nodes = objElem.getChildNodes();
......
......@@ -50,6 +50,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
......@@ -492,7 +493,13 @@ public final class DOMXMLSignature extends DOMStructure
throw new MarshalException(bde);
}
id = DOMUtils.getAttributeValue(sigValueElem, "Id");
Attr attr = sigValueElem.getAttributeNodeNS(null, "Id");
if (attr != null) {
id = attr.getValue();
sigValueElem.setIdAttributeNode(attr, true);
} else {
id = null;
}
this.sigValueElem = sigValueElem;
}
......
......@@ -30,6 +30,7 @@ import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.*;
import javax.xml.crypto.XMLCryptoContext;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
......@@ -104,4 +105,13 @@ public final class Utils {
public static boolean sameDocumentURI(String uri) {
return (uri != null && (uri.length() == 0 || uri.charAt(0) == '#'));
}
static boolean secureValidation(XMLCryptoContext xc) {
return getBoolean(xc, "org.jcp.xml.dsig.secureValidation");
}
private static boolean getBoolean(XMLCryptoContext xc, String name) {
Boolean value = (Boolean)xc.getProperty(name);
return (value != null && value.booleanValue());
}
}
......@@ -197,11 +197,13 @@ package.access=sun.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.security.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.
......@@ -238,11 +240,13 @@ package.definition=sun.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.security.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.
......
......@@ -198,11 +198,13 @@ package.access=sun.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.security.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.,\
......@@ -239,11 +241,13 @@ package.definition=sun.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.security.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.,\
......
......@@ -199,11 +199,13 @@ package.access=sun.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.security.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.
......@@ -239,11 +241,13 @@ package.definition=sun.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.security.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.
......
......@@ -198,11 +198,13 @@ package.access=sun.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.security.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.,\
......@@ -239,11 +241,13 @@ package.definition=sun.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.security.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
org.jcp.xml.dsig.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.,\
......
/*
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2013, 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
......@@ -27,7 +27,7 @@
* @summary Basic unit tests for generating XML Signatures with JSR 105
* @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java
* X509KeySelector.java GenerationTests.java
* @run main GenerationTests
* @run main/othervm GenerationTests
* @author Sean Mullan
*/
......@@ -487,6 +487,7 @@ public class GenerationTests {
Collections.singletonList(obj),
"signature", null);
DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA"), doc);
dsc.setIdAttributeNS(nc, null, "Id");
sig.sign(dsc);
......@@ -494,6 +495,7 @@ public class GenerationTests {
DOMValidateContext dvc = new DOMValidateContext
(kvks, doc.getDocumentElement());
dvc.setIdAttributeNS(nc, null, "Id");
XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
if (sig.equals(sig2) == false) {
......
/*
* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2013, 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
......@@ -140,6 +140,10 @@ public class XMLDSigWithSecMgr implements Runnable {
// validate a signature with SecurityManager enabled
DOMValidateContext dvc = new DOMValidateContext
(kp.getPublic(), envelope.getFirstChild());
// disable secure validation mode so that http reference will work
dvc.setProperty("org.jcp.xml.dsig.secureValidation", Boolean.FALSE);
sig = fac.unmarshalXMLSignature(dvc);
if (!sig.validate(dvc)) {
throw new Exception
......
/*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2013, 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
......@@ -27,7 +27,7 @@
* @summary Basic unit tests for validating XML Signatures with JSR 105
* @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java
* X509KeySelector.java ValidationTests.java
* @run main ValidationTests
* @run main/othervm ValidationTests
* @author Sean Mullan
*/
import java.io.File;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册