Browse Source

#63712 - upgrading xmlsec causes junit tests to fail

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1875392 13f79535-47bb-0310-9956-ffa450edef68
tags/before_ooxml_3rd_edition
Andreas Beeker 4 years ago
parent
commit
88f9cf3ddb

+ 1
- 1
.classpath View File

<classpathentry kind="lib" path="ooxml-testlib/reflections.jar"/> <classpathentry kind="lib" path="ooxml-testlib/reflections.jar"/>
<classpathentry kind="lib" path="ooxml-testlib/guava.jar"/> <classpathentry kind="lib" path="ooxml-testlib/guava.jar"/>
<classpathentry kind="lib" path="ooxml-testlib/javassist.jar"/> <classpathentry kind="lib" path="ooxml-testlib/javassist.jar"/>
<classpathentry exported="true" kind="lib" path="compile-lib/xmlsec-2.1.2.jar"/>
<classpathentry exported="true" kind="lib" path="compile-lib/xmlsec-2.1.5.jar"/>
<classpathentry exported="true" kind="lib" path="lib/commons-codec-1.14.jar"/> <classpathentry exported="true" kind="lib" path="lib/commons-codec-1.14.jar"/>
<classpathentry exported="true" kind="lib" path="lib/commons-logging-1.2.jar"/> <classpathentry exported="true" kind="lib" path="lib/commons-logging-1.2.jar"/>
<classpathentry exported="true" kind="lib" path="lib/commons-collections4-4.4.jar"/> <classpathentry exported="true" kind="lib" path="lib/commons-collections4-4.4.jar"/>

+ 1
- 1
build.gradle View File

compile 'org.apache.commons:commons-collections4:4.4' compile 'org.apache.commons:commons-collections4:4.4'
compile "org.apache.commons:commons-math3:${commonsMathVersion}" compile "org.apache.commons:commons-math3:${commonsMathVersion}"
compile "org.apache.commons:commons-compress:${commonsCompressVersion}" compile "org.apache.commons:commons-compress:${commonsCompressVersion}"
compile 'org.apache.santuario:xmlsec:2.1.2'
compile 'org.apache.santuario:xmlsec:2.1.5'
compile "org.bouncycastle:bcpkix-jdk15on:${bouncyCastleVersion}" compile "org.bouncycastle:bcpkix-jdk15on:${bouncyCastleVersion}"
compile 'com.github.virtuald:curvesapi:1.06' compile 'com.github.virtuald:curvesapi:1.06'
compile 'com.zaxxer:SparseBitSet:1.2' compile 'com.zaxxer:SparseBitSet:1.2'

+ 6
- 2
build.xml View File

value="${repository.m2}/maven2/com/zaxxer/SparseBitSet/1.2/SparseBitSet-1.2.jar"/> value="${repository.m2}/maven2/com/zaxxer/SparseBitSet/1.2/SparseBitSet-1.2.jar"/>


<!-- xml signature libs --> <!-- xml signature libs -->
<property name="dsig.xmlsec.jar" location="${compile.lib}/xmlsec-2.1.2.jar"/>
<property name="dsig.xmlsec.url" value="${repository.m2}/maven2/org/apache/santuario/xmlsec/2.1.2/xmlsec-2.1.2.jar"/>
<property name="dsig.xmlsec.jar" location="${compile.lib}/xmlsec-2.1.5.jar"/>
<property name="dsig.xmlsec.url" value="${repository.m2}/maven2/org/apache/santuario/xmlsec/2.1.5/xmlsec-2.1.5.jar"/>
<property name="dsig.bouncycastle-prov.jar" location="${compile.lib}/bcprov-ext-jdk15on-1.64.jar"/> <property name="dsig.bouncycastle-prov.jar" location="${compile.lib}/bcprov-ext-jdk15on-1.64.jar"/>
<property name="dsig.bouncycastle-prov.url" value="${repository.m2}/maven2/org/bouncycastle/bcprov-ext-jdk15on/1.64/bcprov-ext-jdk15on-1.64.jar"/> <property name="dsig.bouncycastle-prov.url" value="${repository.m2}/maven2/org/bouncycastle/bcprov-ext-jdk15on/1.64/bcprov-ext-jdk15on-1.64.jar"/>
<property name="dsig.bouncycastle-pkix.jar" location="${compile.lib}/bcpkix-jdk15on-1.64.jar"/> <property name="dsig.bouncycastle-pkix.jar" location="${compile.lib}/bcpkix-jdk15on-1.64.jar"/>
<include name="xercesImpl-*.jar"/> <include name="xercesImpl-*.jar"/>
<include name="xmlsec-2.0*.jar"/> <include name="xmlsec-2.0*.jar"/>
<include name="xmlsec-2.1.0.jar"/> <include name="xmlsec-2.1.0.jar"/>
<include name="xmlsec-2.1.1.jar"/>
<include name="xmlsec-2.1.2.jar"/>
<include name="xmlsec-2.1.3.jar"/>
<include name="xmlsec-2.1.4.jar"/>
<include name="bc*jdk15on-1.5*.jar"/> <include name="bc*jdk15on-1.5*.jar"/>
<include name="bc*jdk15on-1.60*.jar"/> <include name="bc*jdk15on-1.60*.jar"/>
<include name="bc*jdk15on-1.61*.jar"/> <include name="bc*jdk15on-1.61*.jar"/>

+ 3
- 3
sonar/ooxml/pom.xml View File

</fileset> </fileset>
</filesets> </filesets>
</configuration> </configuration>
</plugin>
</plugin>




<!-- set jvm parameters for surefire plugin --> <!-- set jvm parameters for surefire plugin -->
<dependency> <dependency>
<groupId>org.apache.santuario</groupId> <groupId>org.apache.santuario</groupId>
<artifactId>xmlsec</artifactId> <artifactId>xmlsec</artifactId>
<version>2.1.2</version>
<version>2.1.5</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>curvesapi</artifactId> <artifactId>curvesapi</artifactId>
<version>1.06</version> <version>1.06</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>

+ 10
- 15
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java View File

* in the classpath:</p> * in the classpath:</p>
* <ul> * <ul>
* <li>BouncyCastle bcpkix and bcprov (tested against 1.64)</li> * <li>BouncyCastle bcpkix and bcprov (tested against 1.64)</li>
* <li>Apache Santuario "xmlsec" (tested against 2.1.2)</li>
* <li>Apache Santuario "xmlsec" (tested against 2.1.5)</li>
* <li>and slf4j-api (tested against 1.7.30)</li> * <li>and slf4j-api (tested against 1.7.30)</li>
* </ul> * </ul>
*/ */
return; return;
} }


EventTarget target = (EventTarget)document;

final EventListener[] el = { null }; final EventListener[] el = { null };
el[0] = (e) -> {
if (!(e instanceof MutationEvent)) {
return;
}
final EventTarget eventTarget = (EventTarget)document;
final String eventType = "DOMSubtreeModified";
final boolean DONT_USE_CAPTURE = false;


MutationEvent mutEvt = (MutationEvent) e;
EventTarget et = mutEvt.getTarget();
if (!(et instanceof Element)) {
return;
el[0] = (e) -> {
if (e instanceof MutationEvent && e.getTarget() instanceof Document) {
eventTarget.removeEventListener(eventType, el[0], DONT_USE_CAPTURE);
sml.handleElement(this, document, eventTarget, el[0]);
eventTarget.addEventListener(eventType, el[0], DONT_USE_CAPTURE);
} }

sml.handleElement(this, (Element) et, target, el[0]);
}; };


SignatureMarshalListener.setListener(target, el[0], true);
eventTarget.addEventListener(eventType, el[0], DONT_USE_CAPTURE);
} }



/** /**
* Helper method for adding informations after the signing. * Helper method for adding informations after the signing.
* Normally {@link #confirmSignature()} is sufficient to be used. * Normally {@link #confirmSignature()} is sufficient to be used.

+ 50
- 21
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureMarshalDefaultListener.java View File



package org.apache.poi.poifs.crypt.dsig; package org.apache.poi.poifs.crypt.dsig;


import static org.apache.poi.poifs.crypt.dsig.SignatureMarshalListener.setListener;
import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.OO_DIGSIG_NS;
import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.XML_DIGSIG_NS;
import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.XML_NS; import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.XML_NS;


import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import org.w3c.dom.events.EventListener; import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget; import org.w3c.dom.events.EventTarget;
import org.w3c.dom.traversal.DocumentTraversal;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;


/** /**
* This listener class is used, to modify the to be digested xml document, * This listener class is used, to modify the to be digested xml document,
* e.g. to register id attributes or set prefixes for registered namespaces * e.g. to register id attributes or set prefixes for registered namespaces
*/ */
public class SignatureMarshalDefaultListener implements SignatureMarshalListener { public class SignatureMarshalDefaultListener implements SignatureMarshalListener {
private final Set<String> IGNORE_NS = new HashSet<>(Arrays.asList(null, XML_NS, XML_DIGSIG_NS));
private final String OBJECT_TAG = "Object";

@Override @Override
public void handleElement(SignatureInfo signatureInfo, Element el, EventTarget target, EventListener parentListener) {
if (el.hasAttribute("Id")) {
el.setIdAttribute("Id", true);
}
public void handleElement(SignatureInfo signatureInfo, Document doc, EventTarget target, EventListener parentListener) {
// see POI #63712 : because of Santuario change r1853805 in XmlSec 2.1.3,
// we have to deal with the whole document now


setListener(target, parentListener, false);
if (OO_DIGSIG_NS.equals(el.getNamespaceURI())) {
String parentNS = el.getParentNode().getNamespaceURI();
if (!OO_DIGSIG_NS.equals(parentNS) && !el.hasAttributeNS(XML_NS, "mdssi")) {
el.setAttributeNS(XML_NS, "xmlns:mdssi", OO_DIGSIG_NS);
}
final DocumentTraversal traversal = (DocumentTraversal) doc;
final Map<String, String> prefixCfg = signatureInfo.getSignatureConfig().getNamespacePrefixes();

final Map<String, String> prefixUsed = new HashMap<>();

NodeList nl = doc.getElementsByTagName(OBJECT_TAG);
final int objLen = nl.getLength();
for (int i=0; i<objLen; i++) {
final Element objNode = (Element)nl.item(i);
getAllNamespaces(traversal, objNode, prefixCfg, prefixUsed);
prefixUsed.forEach((ns, prefix) -> objNode.setAttributeNS(XML_NS, "xmlns:"+prefix, ns));
} }
setPrefix(signatureInfo, el);
setListener(target, parentListener, true);
} }


protected static void setPrefix(SignatureInfo signatureInfo, Node el) {
String prefix = signatureInfo.getSignatureConfig().getNamespacePrefixes().get(el.getNamespaceURI());
if (prefix != null && el.getPrefix() == null) {
el.setPrefix(prefix);
private void getAllNamespaces(DocumentTraversal traversal, Element objNode, Map<String, String> prefixCfg, Map<String, String> prefixUsed) {
prefixUsed.clear();
final NodeIterator iter = traversal.createNodeIterator(objNode, NodeFilter.SHOW_ELEMENT, null, false);
try {
for (Element node; (node = (Element)iter.nextNode()) != null; ) {
setPrefix(node, prefixCfg, prefixUsed);
NamedNodeMap nnm = node.getAttributes();
final int nnmLen = nnm.getLength();
for (int j=0; j<nnmLen; j++) {
setPrefix(nnm.item(j), prefixCfg, prefixUsed);
}
}
} finally {
iter.detach();
} }
}


NodeList nl = el.getChildNodes();
for (int i=0; i<nl.getLength(); i++) {
setPrefix(signatureInfo, nl.item(i));
private void setPrefix(Node node, Map<String,String> prefixCfg, Map<String,String> prefixUsed) {
String ns = node.getNamespaceURI();
String prefix = prefixCfg.get(ns);
if (!IGNORE_NS.contains(prefix)) {
node.setPrefix(prefix);
prefixUsed.put(ns, prefix);
} }
} }
} }

+ 2
- 13
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureMarshalListener.java View File



package org.apache.poi.poifs.crypt.dsig; package org.apache.poi.poifs.crypt.dsig;


import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.w3c.dom.events.EventListener; import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget; import org.w3c.dom.events.EventTarget;


* e.g. to register id attributes or set prefixes for registered namespaces * e.g. to register id attributes or set prefixes for registered namespaces
*/ */
public interface SignatureMarshalListener { public interface SignatureMarshalListener {
void handleElement(SignatureInfo signatureInfo, Element el, EventTarget target, EventListener parentListener);

// helper method to keep it in one place
static void setListener(EventTarget target, EventListener listener, boolean enabled) {
final String type = "DOMSubtreeModified";
final boolean DONT_USE_CAPTURE = false;
if (enabled) {
target.addEventListener(type, listener, DONT_USE_CAPTURE);
} else {
target.removeEventListener(type, listener, DONT_USE_CAPTURE);
}
}
void handleElement(SignatureInfo signatureInfo, Document doc, EventTarget target, EventListener parentListener);
} }

+ 12
- 4
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESSignatureFacet.java View File

import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import org.w3.x2000.x09.xmldsig.DigestMethodType; import org.w3.x2000.x09.xmldsig.DigestMethodType;
import org.w3.x2000.x09.xmldsig.X509IssuerSerialType; import org.w3.x2000.x09.xmldsig.X509IssuerSerialType;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/** /**
* XAdES Signature Facet. Implements XAdES v1.4.1 which is compatible with XAdES * XAdES Signature Facet. Implements XAdES v1.4.1 which is compatible with XAdES


private XMLObject addXadesObject(SignatureInfo signatureInfo, Document document, QualifyingPropertiesType qualifyingProperties) { private XMLObject addXadesObject(SignatureInfo signatureInfo, Document document, QualifyingPropertiesType qualifyingProperties) {
Node qualDocElSrc = qualifyingProperties.getDomNode(); Node qualDocElSrc = qualifyingProperties.getDomNode();
Node qualDocEl = document.importNode(qualDocElSrc, true);
List<XMLStructure> xadesObjectContent = Arrays.asList(new DOMStructure(qualDocEl));
return signatureInfo.getSignatureFactory().newXMLObject(xadesObjectContent, null, null, null);
Element qualDocEl = (Element)document.importNode(qualDocElSrc, true);

NodeList nl = qualDocEl.getElementsByTagNameNS(SignatureFacet.XADES_132_NS, "SignedProperties");
assert(nl.getLength() == 1);
((Element)nl.item(0)).setIdAttribute("Id", true);

List<XMLStructure> xadesObjectContent = Collections.singletonList(new DOMStructure(qualDocEl));
XMLObject xo = signatureInfo.getSignatureFactory().newXMLObject(xadesObjectContent, null, null, null);
return xo;
} }


private Reference addXadesReference(SignatureInfo signatureInfo) throws XMLSignatureException { private Reference addXadesReference(SignatureInfo signatureInfo) throws XMLSignatureException {

Loading…
Cancel
Save