You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by gi...@apache.org on 2012/09/16 15:06:43 UTC
svn commit: r1385257 - in /santuario/xml-security-java/trunk/src:
main/java/org/apache/xml/security/stax/ext/
main/java/org/apache/xml/security/stax/impl/
main/java/org/apache/xml/security/stax/impl/processor/output/
test/java/org/apache/xml/security/t...
Author: giger
Date: Sun Sep 16 13:06:42 2012
New Revision: 1385257
URL: http://svn.apache.org/viewvc?rev=1385257&view=rev
Log:
SANTUARIO-341 - Support C14N PrefixList for outbound signature in stax code
Modified:
santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/AbstractOutputProcessor.java
santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java
santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityUtils.java
santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/SignaturePartDef.java
santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureEndingOutputProcessor.java
santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureOutputProcessor.java
santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureEndingOutputProcessor.java
santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureOutputProcessor.java
santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java
Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/AbstractOutputProcessor.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/AbstractOutputProcessor.java?rev=1385257&r1=1385256&r2=1385257&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/AbstractOutputProcessor.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/AbstractOutputProcessor.java Sun Sep 16 13:06:42 2012
@@ -155,7 +155,7 @@ public abstract class AbstractOutputProc
outputAsEvent(outputProcessorChain, xmlSecStartElement);
}
- public void createStartElementAndOutputAsEvent(
+ public XMLSecStartElement createStartElementAndOutputAsEvent(
OutputProcessorChain outputProcessorChain, QName element,
boolean outputLocalNs, List<XMLSecAttribute> attributes) throws XMLStreamException, XMLSecurityException {
@@ -186,6 +186,7 @@ public abstract class AbstractOutputProc
XMLSecStartElement xmlSecStartElement
= XMLSecEventFactory.createXmlSecStartElement(element, attributes, comparableNamespaces);
outputAsEvent(outputProcessorChain, xmlSecStartElement);
+ return xmlSecStartElement;
}
public XMLSecEndElement createEndElement(QName element) {
Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java?rev=1385257&r1=1385256&r2=1385257&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java Sun Sep 16 13:06:42 2012
@@ -198,6 +198,7 @@ public class XMLSecurityProperties {
private boolean useSingleCert = true;
private Key signatureKey;
private X509Certificate[] signatureCerts;
+ private boolean addExcC14NInclusivePrefixes = false;
public X509Certificate[] getSignatureCerts() {
return signatureCerts;
@@ -248,6 +249,14 @@ public class XMLSecurityProperties {
this.useSingleCert = useSingleCert;
}
+ public boolean isAddExcC14NInclusivePrefixes() {
+ return addExcC14NInclusivePrefixes;
+ }
+
+ public void setAddExcC14NInclusivePrefixes(boolean addExcC14NInclusivePrefixes) {
+ this.addExcC14NInclusivePrefixes = addExcC14NInclusivePrefixes;
+ }
+
/**
* Returns the actual set actions
*
Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityUtils.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityUtils.java?rev=1385257&r1=1385256&r2=1385257&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityUtils.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityUtils.java Sun Sep 16 13:06:42 2012
@@ -23,6 +23,8 @@ import org.apache.xml.security.keys.cont
import org.apache.xml.security.stax.config.TransformerAlgorithmMapper;
import org.apache.xml.security.stax.ext.stax.XMLSecAttribute;
import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
+import org.apache.xml.security.stax.ext.stax.XMLSecNamespace;
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
import org.apache.xml.security.stax.impl.algorithms.ECDSAUtils;
import javax.security.auth.callback.Callback;
@@ -42,9 +44,7 @@ import java.security.cert.X509Certificat
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
/**
* @author $Author$
@@ -309,4 +309,49 @@ public class XMLSecurityUtils {
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_dsig_X509Data);
}
+
+ public static Set<String> getExcC14NInclusiveNamespacePrefixes(XMLSecStartElement xmlSecStartElement, boolean excludeVisible) {
+
+ if (xmlSecStartElement == null) {
+ return Collections.emptySet();
+ }
+ Set<String> prefixes = new HashSet<String>();
+
+ XMLSecStartElement parentXMXmlSecStartElement = xmlSecStartElement.getParentXMLSecStartElement();
+ if (parentXMXmlSecStartElement != null) {
+ List<XMLSecNamespace> onElementDeclaredNamespaces = parentXMXmlSecStartElement.getOnElementDeclaredNamespaces();
+ List<XMLSecNamespace> xmlSecNamespaces = new ArrayList<XMLSecNamespace>();
+ parentXMXmlSecStartElement.getNamespacesFromCurrentScope(xmlSecNamespaces);
+ xmlSecNamespaces = xmlSecNamespaces.subList(0, xmlSecNamespaces.size() - onElementDeclaredNamespaces.size());
+
+ //reverse iteration -> From current element namespaces to parent namespaces
+ for (int i = xmlSecNamespaces.size() - 1; i >= 0; i--) {
+ XMLSecNamespace xmlSecNamespace = xmlSecNamespaces.get(i);
+ String prefix = xmlSecNamespace.getPrefix();
+ if (prefix == null || prefix.isEmpty()) {
+ prefixes.add("#default");
+ } else {
+ prefixes.add(xmlSecNamespace.getPrefix());
+ }
+ }
+
+ if (excludeVisible) {
+ for (int i = 0; i < onElementDeclaredNamespaces.size(); i++) {
+ XMLSecNamespace xmlSecNamespace = onElementDeclaredNamespaces.get(i);
+ String prefix = xmlSecNamespace.getPrefix();
+ if (prefix == null || prefix.isEmpty()) {
+ prefixes.remove("#default");
+ } else {
+ prefixes.remove(prefix);
+ }
+ }
+ if (xmlSecStartElement.getName().getPrefix() == null || xmlSecStartElement.getName().getPrefix().isEmpty()) {
+ prefixes.remove("#default");
+ } else {
+ prefixes.remove(xmlSecStartElement.getName().getPrefix());
+ }
+ }
+ }
+ return prefixes;
+ }
}
Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/SignaturePartDef.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/SignaturePartDef.java?rev=1385257&r1=1385256&r2=1385257&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/SignaturePartDef.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/SignaturePartDef.java Sun Sep 16 13:06:42 2012
@@ -30,7 +30,8 @@ public class SignaturePartDef {
private String digestValue;
private String[] transforms;
private String digestAlgo;
- private String inclusiveNamespaces;
+ private String inclusiveNamespacesPrefixes;
+ private boolean excludeVisibleC14Nprefixes;
private boolean externalResource;
private boolean generateXPointer;
@@ -66,12 +67,20 @@ public class SignaturePartDef {
this.digestAlgo = digestAlgo;
}
- public String getInclusiveNamespaces() {
- return inclusiveNamespaces;
+ public String getInclusiveNamespacesPrefixes() {
+ return inclusiveNamespacesPrefixes;
}
- public void setInclusiveNamespaces(String inclusiveNamespaces) {
- this.inclusiveNamespaces = inclusiveNamespaces;
+ public void setInclusiveNamespacesPrefixes(String inclusiveNamespacesPrefixes) {
+ this.inclusiveNamespacesPrefixes = inclusiveNamespacesPrefixes;
+ }
+
+ public boolean isExcludeVisibleC14Nprefixes() {
+ return excludeVisibleC14Nprefixes;
+ }
+
+ public void setExcludeVisibleC14Nprefixes(boolean excludeVisibleC14Nprefixes) {
+ this.excludeVisibleC14Nprefixes = excludeVisibleC14Nprefixes;
}
public boolean isExternalResource() {
Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureEndingOutputProcessor.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureEndingOutputProcessor.java?rev=1385257&r1=1385256&r2=1385257&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureEndingOutputProcessor.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureEndingOutputProcessor.java Sun Sep 16 13:06:42 2012
@@ -22,6 +22,7 @@ import org.apache.commons.codec.binary.B
import org.apache.xml.security.stax.ext.*;
import org.apache.xml.security.stax.ext.stax.XMLSecAttribute;
import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
import org.apache.xml.security.stax.impl.SignaturePartDef;
import org.apache.xml.security.stax.impl.algorithms.SignatureAlgorithm;
import org.apache.xml.security.stax.impl.algorithms.SignatureAlgorithmFactory;
@@ -39,6 +40,7 @@ import java.security.NoSuchProviderExcep
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
/**
* @author $Author$
@@ -95,7 +97,7 @@ public abstract class AbstractSignatureE
List<XMLSecAttribute> attributes = new ArrayList<XMLSecAttribute>(1);
attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Id, IDGenerator.generateID(null)));
- createStartElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_dsig_Signature, true, attributes);
+ XMLSecStartElement signatureElement = createStartElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_dsig_Signature, true, attributes);
SignatureAlgorithm signatureAlgorithm;
@@ -122,13 +124,21 @@ public abstract class AbstractSignatureE
signatureAlgorithm.engineInitSign(wrappingSecurityToken.getSecretKey(getSecurityProperties().getSignatureAlgorithm()));
- SignedInfoProcessor signedInfoProcessor = newSignedInfoProcessor(signatureAlgorithm, subOutputProcessorChain);
-
+ SignedInfoProcessor signedInfoProcessor = newSignedInfoProcessor(signatureAlgorithm, signatureElement, subOutputProcessorChain);
createStartElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_dsig_SignedInfo, false, null);
attributes = new ArrayList<XMLSecAttribute>(1);
- attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm, getSecurityProperties().getSignatureCanonicalizationAlgorithm()));
+ final String signatureCanonicalizationAlgorithm = getSecurityProperties().getSignatureCanonicalizationAlgorithm();
+ attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm, signatureCanonicalizationAlgorithm));
createStartElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_dsig_CanonicalizationMethod, false, attributes);
+
+ if (getSecurityProperties().isAddExcC14NInclusivePrefixes() && XMLSecurityConstants.NS_C14N_EXCL.equals(signatureCanonicalizationAlgorithm)) {
+ attributes = new ArrayList<XMLSecAttribute>(1);
+ attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_PrefixList, signedInfoProcessor.getInclusiveNamespacePrefixes()));
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_c14nExcl_InclusiveNamespaces, true, attributes);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_c14nExcl_InclusiveNamespaces);
+ }
+
createEndElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_dsig_CanonicalizationMethod);
attributes = new ArrayList<XMLSecAttribute>(1);
@@ -178,15 +188,9 @@ public abstract class AbstractSignatureE
createEndElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_dsig_Signature);
}
- protected SignedInfoProcessor newSignedInfoProcessor(SignatureAlgorithm signatureAlgorithm, OutputProcessorChain outputProcessorChain)
- throws XMLSecurityException {
- SignedInfoProcessor signedInfoProcessor = new SignedInfoProcessor(signatureAlgorithm);
- signedInfoProcessor.setXMLSecurityProperties(getSecurityProperties());
- signedInfoProcessor.setAction(getAction());
- signedInfoProcessor.addAfterProcessor(AbstractSignatureEndingOutputProcessor.class.getName());
- signedInfoProcessor.init(outputProcessorChain);
- return signedInfoProcessor;
- }
+ protected abstract SignedInfoProcessor newSignedInfoProcessor(
+ SignatureAlgorithm signatureAlgorithm, XMLSecStartElement xmlSecStartElement, OutputProcessorChain outputProcessorChain)
+ throws XMLSecurityException;
protected abstract void createTransformsStructureForSignature(
OutputProcessorChain subOutputProcessorChain,
@@ -204,11 +208,15 @@ public abstract class AbstractSignatureE
private OutputStream bufferedSignerOutputStream;
private Transformer transformer;
private byte[] signatureValue = null;
+ private String inclusiveNamespacePrefixes = null;
private SignatureAlgorithm signatureAlgorithm;
+ private XMLSecStartElement xmlSecStartElement;
- public SignedInfoProcessor(SignatureAlgorithm signatureAlgorithm) throws XMLSecurityException {
+ public SignedInfoProcessor(SignatureAlgorithm signatureAlgorithm, XMLSecStartElement xmlSecStartElement)
+ throws XMLSecurityException {
super();
this.signatureAlgorithm = signatureAlgorithm;
+ this.xmlSecStartElement = xmlSecStartElement;
}
@Override
@@ -217,9 +225,28 @@ public abstract class AbstractSignatureE
this.signerOutputStream = new SignerOutputStream(this.signatureAlgorithm);
this.bufferedSignerOutputStream = new BufferedOutputStream(this.signerOutputStream);
+ final String canonicalizationAlgorithm = getSecurityProperties().getSignatureCanonicalizationAlgorithm();
+
+ List<String> inclusiveNamespacePrefixes = null;
+ if (getSecurityProperties().isAddExcC14NInclusivePrefixes() &&
+ XMLSecurityConstants.NS_C14N_EXCL.equals(canonicalizationAlgorithm)) {
+
+ Set<String> prefixSet = XMLSecurityUtils.getExcC14NInclusiveNamespacePrefixes(xmlSecStartElement, false);
+ StringBuilder prefixes = new StringBuilder();
+ for (Iterator<String> iterator = prefixSet.iterator(); iterator.hasNext(); ) {
+ String prefix = iterator.next();
+ if (prefixes.length() != 0) {
+ prefixes.append(" ");
+ }
+ prefixes.append(prefix);
+ }
+ inclusiveNamespacePrefixes = new ArrayList<String>(prefixSet);
+ this.inclusiveNamespacePrefixes = prefixes.toString();
+ }
+
try {
- this.transformer = XMLSecurityUtils.getTransformer(null, this.bufferedSignerOutputStream,
- getSecurityProperties().getSignatureCanonicalizationAlgorithm(), XMLSecurityConstants.DIRECTION.OUT);
+ this.transformer = XMLSecurityUtils.getTransformer(inclusiveNamespacePrefixes, this.bufferedSignerOutputStream,
+ canonicalizationAlgorithm, XMLSecurityConstants.DIRECTION.OUT);
} catch (NoSuchMethodException e) {
throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_SIGNATURE, e);
} catch (InstantiationException e) {
@@ -249,6 +276,10 @@ public abstract class AbstractSignatureE
}
}
+ public String getInclusiveNamespacePrefixes() {
+ return inclusiveNamespacePrefixes;
+ }
+
@Override
public void processEvent(XMLSecEvent xmlSecEvent, OutputProcessorChain outputProcessorChain)
throws XMLStreamException, XMLSecurityException {
Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureOutputProcessor.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureOutputProcessor.java?rev=1385257&r1=1385256&r2=1385257&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureOutputProcessor.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureOutputProcessor.java Sun Sep 16 13:06:42 2012
@@ -26,12 +26,12 @@ import org.apache.xml.security.stax.conf
import org.apache.xml.security.stax.config.ResourceResolverMapper;
import org.apache.xml.security.stax.ext.*;
import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
import org.apache.xml.security.stax.impl.SignaturePartDef;
import org.apache.xml.security.stax.impl.transformer.TransformIdentity;
import org.apache.xml.security.stax.impl.util.DigestOutputStream;
import org.xmlsecurity.ns.configuration.AlgorithmType;
-import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import java.io.BufferedOutputStream;
@@ -42,10 +42,7 @@ import java.lang.reflect.InvocationTarge
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
/**
* @author $Author$
@@ -92,9 +89,21 @@ public abstract class AbstractSignatureO
InputStream inputStream = resourceResolver.getInputStreamFromExternalReference();
+ SignaturePartDef signaturePartDef = new SignaturePartDef();
+ signaturePartDef.setSigRefId(externalReference);
+ signaturePartDef.setExternalResource(true);
+ signaturePartDef.setTransforms(securePart.getTransforms());
+ String digestMethod = securePart.getDigestMethod();
+ if (digestMethod == null) {
+ digestMethod = getSecurityProperties().getSignatureDigestAlgorithm();
+ }
+ signaturePartDef.setDigestAlgo(digestMethod);
+ getSignaturePartDefList().add(signaturePartDef);
+
try {
if (securePart.getTransforms() != null) {
- Transformer transformer = buildTransformerChain(digestOutputStream, securePart.getTransforms());
+ signaturePartDef.setExcludeVisibleC14Nprefixes(true);
+ Transformer transformer = buildTransformerChain(digestOutputStream, signaturePartDef, null);
transformer.transform(inputStream);
transformer.doFinal();
} else {
@@ -118,17 +127,7 @@ public abstract class AbstractSignatureO
logger.debug("Calculated Digest: " + calculatedDigest);
}
- SignaturePartDef signaturePartDef = new SignaturePartDef();
- signaturePartDef.setSigRefId(externalReference);
signaturePartDef.setDigestValue(calculatedDigest);
- signaturePartDef.setExternalResource(true);
- signaturePartDef.setTransforms(securePart.getTransforms());
- String digestMethod = securePart.getDigestMethod();
- if (digestMethod == null) {
- digestMethod = getSecurityProperties().getSignatureDigestAlgorithm();
- }
- signaturePartDef.setDigestAlgo(digestMethod);
- getSignaturePartDefList().add(signaturePartDef);
}
}
@@ -144,7 +143,9 @@ public abstract class AbstractSignatureO
this.activeInternalSignatureOutputProcessor = activeInternalSignatureOutputProcessor;
}
- private DigestOutputStream createMessageDigestOutputStream(String digestAlgorithm) throws XMLSecurityException, NoSuchAlgorithmException, NoSuchProviderException {
+ private DigestOutputStream createMessageDigestOutputStream(String digestAlgorithm)
+ throws XMLSecurityException, NoSuchAlgorithmException, NoSuchProviderException {
+
AlgorithmType algorithmType = JCEAlgorithmMapper.getAlgorithmMapping(digestAlgorithm);
if (algorithmType == null) {
throw new XMLSecurityException(XMLSecurityException.ErrorCode.UNSUPPORTED_ALGORITHM, "unknownSignatureAlgorithm", digestAlgorithm);
@@ -158,10 +159,14 @@ public abstract class AbstractSignatureO
return new DigestOutputStream(messageDigest);
}
- protected Transformer buildTransformerChain(OutputStream outputStream, String[] transforms)
+ protected Transformer buildTransformerChain(OutputStream outputStream,
+ SignaturePartDef signaturePartDef,
+ XMLSecStartElement xmlSecStartElement)
throws XMLSecurityException, NoSuchMethodException, InstantiationException,
IllegalAccessException, InvocationTargetException {
+ String[] transforms = signaturePartDef.getTransforms();
+
if (transforms == null || transforms.length == 0) {
Transformer transformer = new TransformIdentity();
transformer.setOutputStream(outputStream);
@@ -172,12 +177,31 @@ public abstract class AbstractSignatureO
for (int i = transforms.length - 1; i >= 0; i--) {
String transform = transforms[i];
+ List<String> inclusiveNamespacePrefixes = null;
+ if (getSecurityProperties().isAddExcC14NInclusivePrefixes() &&
+ XMLSecurityConstants.NS_C14N_EXCL.equals(transform)) {
+
+ Set<String> prefixSet = XMLSecurityUtils.getExcC14NInclusiveNamespacePrefixes(
+ xmlSecStartElement, signaturePartDef.isExcludeVisibleC14Nprefixes()
+ );
+ StringBuilder prefixes = new StringBuilder();
+ for (Iterator<String> iterator = prefixSet.iterator(); iterator.hasNext(); ) {
+ String prefix = iterator.next();
+ if (prefixes.length() != 0) {
+ prefixes.append(" ");
+ }
+ prefixes.append(prefix);
+ }
+ inclusiveNamespacePrefixes = new ArrayList<String>(prefixSet);
+ signaturePartDef.setInclusiveNamespacesPrefixes(prefixes.toString());
+ }
+
if (parentTransformer != null) {
parentTransformer = XMLSecurityUtils.getTransformer(
parentTransformer, null, transform, XMLSecurityConstants.DIRECTION.OUT);
} else {
parentTransformer = XMLSecurityUtils.getTransformer(
- null, outputStream, transform, XMLSecurityConstants.DIRECTION.OUT);
+ inclusiveNamespacePrefixes, outputStream, transform, XMLSecurityConstants.DIRECTION.OUT);
}
}
return parentTransformer;
@@ -186,19 +210,19 @@ public abstract class AbstractSignatureO
public class InternalSignatureOutputProcessor extends AbstractOutputProcessor {
private SignaturePartDef signaturePartDef;
- private QName startElement;
+ private XMLSecStartElement xmlSecStartElement;
private int elementCounter = 0;
private OutputStream bufferedDigestOutputStream;
private DigestOutputStream digestOutputStream;
private Transformer transformer;
- public InternalSignatureOutputProcessor(SignaturePartDef signaturePartDef, QName startElement)
+ public InternalSignatureOutputProcessor(SignaturePartDef signaturePartDef, XMLSecStartElement xmlSecStartElement)
throws XMLSecurityException, NoSuchProviderException, NoSuchAlgorithmException {
super();
this.addBeforeProcessor(InternalSignatureOutputProcessor.class.getName());
this.signaturePartDef = signaturePartDef;
- this.startElement = startElement;
+ this.xmlSecStartElement = xmlSecStartElement;
}
@Override
@@ -206,7 +230,7 @@ public abstract class AbstractSignatureO
try {
this.digestOutputStream = createMessageDigestOutputStream(signaturePartDef.getDigestAlgo());
this.bufferedDigestOutputStream = new BufferedOutputStream(digestOutputStream);
- this.transformer = buildTransformerChain(this.bufferedDigestOutputStream, signaturePartDef.getTransforms());
+ this.transformer = buildTransformerChain(this.bufferedDigestOutputStream, signaturePartDef, xmlSecStartElement);
} catch (NoSuchMethodException e) {
throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_SIGNATURE, e);
} catch (InstantiationException e) {
@@ -236,7 +260,9 @@ public abstract class AbstractSignatureO
case XMLStreamConstants.END_ELEMENT:
elementCounter--;
- if (elementCounter == 0 && xmlSecEvent.asEndElement().getName().equals(this.startElement)) {
+ if (elementCounter == 0 &&
+ xmlSecEvent.asEndElement().getName().equals(this.xmlSecStartElement.getName())) {
+
transformer.doFinal();
try {
bufferedDigestOutputStream.close();
Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureEndingOutputProcessor.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureEndingOutputProcessor.java?rev=1385257&r1=1385256&r2=1385257&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureEndingOutputProcessor.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureEndingOutputProcessor.java Sun Sep 16 13:06:42 2012
@@ -31,6 +31,7 @@ import org.apache.xml.security.stax.ext.
import org.apache.xml.security.stax.ext.XMLSecurityUtils;
import org.apache.xml.security.stax.ext.stax.XMLSecAttribute;
import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
import org.apache.xml.security.stax.impl.SignaturePartDef;
import org.apache.xml.security.stax.impl.algorithms.SignatureAlgorithm;
import org.apache.xml.security.stax.impl.securityToken.OutboundSecurityToken;
@@ -49,8 +50,11 @@ public class XMLSignatureEndingOutputPro
}
@Override
- protected SignedInfoProcessor newSignedInfoProcessor(SignatureAlgorithm signatureAlgorithm, OutputProcessorChain outputProcessorChain) throws XMLSecurityException {
- this.signedInfoProcessor = new SignedInfoProcessor(signatureAlgorithm);
+ protected SignedInfoProcessor newSignedInfoProcessor(
+ SignatureAlgorithm signatureAlgorithm, XMLSecStartElement xmlSecStartElement,
+ OutputProcessorChain outputProcessorChain) throws XMLSecurityException {
+
+ this.signedInfoProcessor = new SignedInfoProcessor(signatureAlgorithm, xmlSecStartElement);
this.signedInfoProcessor.setXMLSecurityProperties(getSecurityProperties());
this.signedInfoProcessor.setAction(getAction());
this.signedInfoProcessor.addAfterProcessor(XMLSignatureEndingOutputProcessor.class.getName());
@@ -120,6 +124,14 @@ public class XMLSignatureEndingOutputPro
List<XMLSecAttribute> attributes = new ArrayList<XMLSecAttribute>(1);
attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm, transform));
createStartElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_dsig_Transform, false, attributes);
+
+ if (getSecurityProperties().isAddExcC14NInclusivePrefixes()) {
+ attributes = new ArrayList<XMLSecAttribute>(1);
+ attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_PrefixList, signaturePartDef.getInclusiveNamespacesPrefixes()));
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_c14nExcl_InclusiveNamespaces, true, attributes);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_c14nExcl_InclusiveNamespaces);
+ }
+
createEndElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_dsig_Transform);
}
createEndElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_dsig_Transforms);
Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureOutputProcessor.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureOutputProcessor.java?rev=1385257&r1=1385256&r2=1385257&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureOutputProcessor.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureOutputProcessor.java Sun Sep 16 13:06:42 2012
@@ -74,6 +74,7 @@ public class XMLSignatureOutputProcessor
try {
SignaturePartDef signaturePartDef = new SignaturePartDef();
signaturePartDef.setTransforms(securePart.getTransforms());
+ signaturePartDef.setExcludeVisibleC14Nprefixes(true);
String digestMethod = securePart.getDigestMethod();
if (digestMethod == null) {
digestMethod = getSecurityProperties().getSignatureDigestAlgorithm();
@@ -115,7 +116,7 @@ public class XMLSignatureOutputProcessor
}
getSignaturePartDefList().add(signaturePartDef);
- internalSignatureOutputProcessor = new InternalSignatureOutputProcessor(signaturePartDef, xmlSecStartElement.getName());
+ internalSignatureOutputProcessor = new InternalSignatureOutputProcessor(signaturePartDef, xmlSecStartElement);
internalSignatureOutputProcessor.setXMLSecurityProperties(getSecurityProperties());
internalSignatureOutputProcessor.setAction(getAction());
internalSignatureOutputProcessor.addAfterProcessor(XMLSignatureOutputProcessor.class.getName());
@@ -137,5 +138,4 @@ public class XMLSignatureOutputProcessor
}
outputProcessorChain.processEvent(xmlSecEvent);
}
-
}
Modified: santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java?rev=1385257&r1=1385256&r2=1385257&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java (original)
+++ santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java Sun Sep 16 13:06:42 2012
@@ -618,6 +618,57 @@ public class SignatureCreationTest exten
}
@Test
+ public void testExcC14nInclusivePrefixes() throws Exception {
+ // Set up the Configuration
+ XMLSecurityProperties properties = new XMLSecurityProperties();
+ XMLSecurityConstants.Action[] actions =
+ new XMLSecurityConstants.Action[]{XMLSecurityConstants.SIGNATURE};
+ properties.setOutAction(actions);
+
+ // Set the key up
+ KeyStore keyStore = KeyStore.getInstance("jks");
+ keyStore.load(
+ this.getClass().getClassLoader().getResource("transmitter.jks").openStream(),
+ "default".toCharArray()
+ );
+ Key key = keyStore.getKey("transmitter", "default".toCharArray());
+ properties.setSignatureKey(key);
+ X509Certificate cert = (X509Certificate)keyStore.getCertificate("transmitter");
+ properties.setSignatureCerts(new X509Certificate[]{cert});
+
+ properties.setSignatureCanonicalizationAlgorithm(XMLSecurityConstants.NS_C14N_EXCL);
+ properties.setAddExcC14NInclusivePrefixes(true);
+
+ SecurePart securePart =
+ new SecurePart(new QName("urn:example:po", "PaymentInfo"), SecurePart.Modifier.Content);
+ properties.addSignaturePart(securePart);
+
+ OutboundXMLSec outboundXMLSec = XMLSec.getOutboundXMLSec(properties);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ XMLStreamWriter xmlStreamWriter = outboundXMLSec.processOutMessage(baos, "UTF-8");
+
+ InputStream sourceDocument =
+ this.getClass().getClassLoader().getResourceAsStream(
+ "ie/baltimore/merlin-examples/merlin-xmlenc-five/plaintext.xml");
+ XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(sourceDocument);
+
+ XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
+ xmlStreamWriter.close();
+
+ //System.out.println("Got:\n" + new String(baos.toByteArray(), "UTF-8"));
+ Document document =
+ documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
+
+ NodeList nodeList = document.getElementsByTagNameNS(XMLSecurityConstants.TAG_c14nExcl_InclusiveNamespaces.getNamespaceURI(), XMLSecurityConstants.TAG_c14nExcl_InclusiveNamespaces.getLocalPart());
+ Assert.assertEquals(2, nodeList.getLength());
+ Assert.assertEquals("", ((Element)nodeList.item(0)).getAttribute(XMLSecurityConstants.ATT_NULL_PrefixList.getLocalPart()));
+ Assert.assertEquals("", ((Element)nodeList.item(1)).getAttribute(XMLSecurityConstants.ATT_NULL_PrefixList.getLocalPart()));
+
+ // Verify using DOM
+ verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ }
+
+ @Test
public void testSignatureCreationKeyValue() throws Exception {
// Set up the Configuration
XMLSecurityProperties properties = new XMLSecurityProperties();