summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Beeker <kiwiwings@apache.org>2020-03-01 22:20:38 +0000
committerAndreas Beeker <kiwiwings@apache.org>2020-03-01 22:20:38 +0000
commitb04379bc4ca1faffe2b834f26e247ba74317ce38 (patch)
treee859045db0b4ae5314123c5b1671122cce7b46f6
parent369170467880ccab6c4cc9aeeae1caae15d0a469 (diff)
downloadpoi-b04379bc4ca1faffe2b834f26e247ba74317ce38.tar.gz
poi-b04379bc4ca1faffe2b834f26e247ba74317ce38.zip
#64186 - Decrease usage of ThreadLocals in XML Signature API
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1874671 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/ooxml/java/org/apache/poi/poifs/crypt/dsig/OOXMLURIDereferencer.java31
-rw-r--r--src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java210
-rw-r--r--src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java363
-rw-r--r--src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureMarshalDefaultListener.java63
-rw-r--r--src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureMarshalListener.java76
-rw-r--r--src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignaturePart.java42
-rw-r--r--src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/EnvelopedSignatureFacet.java22
-rw-r--r--src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/KeyInfoSignatureFacet.java25
-rw-r--r--src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/OOXMLSignatureFacet.java94
-rw-r--r--src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/Office2010SignatureFacet.java21
-rw-r--r--src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/SignatureFacet.java103
-rw-r--r--src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/SignatureFacetHelper.java75
-rw-r--r--src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESSignatureFacet.java69
-rw-r--r--src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESXLSignatureFacet.java57
-rw-r--r--src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java28
-rw-r--r--src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampService.java17
-rw-r--r--src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java385
17 files changed, 875 insertions, 806 deletions
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/OOXMLURIDereferencer.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/OOXMLURIDereferencer.java
index b4061622e0..b809b06ef5 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/OOXMLURIDereferencer.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/OOXMLURIDereferencer.java
@@ -18,9 +18,9 @@
/* ====================================================================
This product contains an ASLv2 licensed version of the OOXML signer
package from the eID Applet project
- http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
Copyright (C) 2008-2014 FedICT.
- ================================================================= */
+ ================================================================= */
package org.apache.poi.poifs.crypt.dsig;
@@ -42,33 +42,29 @@ import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
-import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
/**
* JSR105 URI dereferencer for Office Open XML documents.
*/
-public class OOXMLURIDereferencer implements URIDereferencer, SignatureConfigurable {
+public class OOXMLURIDereferencer implements URIDereferencer {
private static final POILogger LOG = POILogFactory.getLogger(OOXMLURIDereferencer.class);
- private SignatureConfig signatureConfig;
+ private SignatureInfo signatureInfo;
private URIDereferencer baseUriDereferencer;
- public void setSignatureConfig(SignatureConfig signatureConfig) {
- this.signatureConfig = signatureConfig;
+ public void setSignatureInfo(SignatureInfo signatureInfo) {
+ this.signatureInfo = signatureInfo;
+ baseUriDereferencer = signatureInfo.getSignatureFactory().getURIDereferencer();
}
public Data dereference(URIReference uriReference, XMLCryptoContext context) throws URIReferenceException {
- if (baseUriDereferencer == null) {
- baseUriDereferencer = signatureConfig.getSignatureFactory().getURIDereferencer();
+ if (uriReference == null) {
+ throw new NullPointerException("URIReference cannot be null - call setSignatureInfo(...) before");
}
-
- if (null == uriReference) {
- throw new NullPointerException("URIReference cannot be null");
- }
- if (null == context) {
+ if (context == null) {
throw new NullPointerException("XMLCryptoContext cannot be null");
}
@@ -82,7 +78,7 @@ public class OOXMLURIDereferencer implements URIDereferencer, SignatureConfigura
PackagePart part = findPart(uri);
if (part == null) {
LOG.log(POILogger.DEBUG, "cannot resolve, delegating to base DOM URI dereferencer", uri);
- return this.baseUriDereferencer.dereference(uriReference, context);
+ return baseUriDereferencer.dereference(uriReference, context);
}
InputStream dataStream;
@@ -116,15 +112,14 @@ public class OOXMLURIDereferencer implements URIDereferencer, SignatureConfigura
LOG.log(POILogger.DEBUG, "illegal part name (expected)", uri);
return null;
}
-
+
PackagePartName ppn;
try {
ppn = PackagingURIHelper.createPartName(path);
+ return signatureInfo.getOpcPackage().getPart(ppn);
} catch (InvalidFormatException e) {
LOG.log(POILogger.WARN, "illegal part name (not expected)", uri);
return null;
}
-
- return signatureConfig.getOpcPackage().getPart(ppn);
}
}
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java
index 0fcacaf376..f122b36296 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java
@@ -27,12 +27,15 @@ import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
import javax.xml.crypto.URIDereferencer;
import javax.xml.crypto.dsig.CanonicalizationMethod;
@@ -53,11 +56,12 @@ import org.apache.poi.poifs.crypt.dsig.services.SignaturePolicyService;
import org.apache.poi.poifs.crypt.dsig.services.TSPTimeStampService;
import org.apache.poi.poifs.crypt.dsig.services.TimeStampService;
import org.apache.poi.poifs.crypt.dsig.services.TimeStampServiceValidator;
+import org.apache.poi.util.Internal;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
+import org.apache.poi.util.Removal;
import org.apache.xml.security.signature.XMLSignature;
-import org.w3c.dom.events.EventListener;
/**
* This class bundles the configuration options used for the existing
@@ -73,11 +77,16 @@ public class SignatureConfig {
private static final POILogger LOG = POILogFactory.getLogger(SignatureConfig.class);
private static final String DigestMethod_SHA224 = "http://www.w3.org/2001/04/xmldsig-more#sha224";
private static final String DigestMethod_SHA384 = "http://www.w3.org/2001/04/xmldsig-more#sha384";
+ private static final String XMLSEC_SANTUARIO = "org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI";
+ private static final String XMLSEC_JDK = "org.jcp.xml.dsig.internal.dom.XMLDSigRI";
+ private static final List<Supplier<SignatureFacet>> DEFAULT_FACETS = Arrays.asList(
+ OOXMLSignatureFacet::new,
+ KeyInfoSignatureFacet::new,
+ XAdESSignatureFacet::new,
+ Office2010SignatureFacet::new
+ );
- public interface SignatureConfigurable {
- void setSignatureConfig(SignatureConfig signatureConfig);
- }
private ThreadLocal<OPCPackage> opcPackage = new ThreadLocal<>();
private ThreadLocal<XMLSignatureFactory> signatureFactory = new ThreadLocal<>();
@@ -94,7 +103,7 @@ public class SignatureConfig {
* the optional signature policy service used for XAdES-EPES.
*/
private SignaturePolicyService signaturePolicyService;
- private URIDereferencer uriDereferencer;
+ private URIDereferencer uriDereferencer = new OOXMLURIDereferencer();
private String canonicalizationMethod = CanonicalizationMethod.INCLUSIVE;
private boolean includeEntireCertificateChain = true;
@@ -161,7 +170,7 @@ public class SignatureConfig {
* with certain namespaces, so this EventListener is used to interfere
* with the marshalling process.
*/
- private EventListener signatureMarshalListener;
+ private SignatureMarshalListener signatureMarshalListener = new SignatureMarshalDefaultListener();
/**
* Map of namespace uris to prefix
@@ -181,61 +190,11 @@ public class SignatureConfig {
*/
private boolean allowMultipleSignatures = false;
-
- /**
- * Inits and checks the config object.
- * If not set previously, complex configuration properties also get
- * created/initialized via this initialization call.
- *
- * @param onlyValidation if true, only a subset of the properties
- * is initialized, which are necessary for validation. If false,
- * also the other properties needed for signing are been taken care of
- */
- protected void init(boolean onlyValidation) {
- if (opcPackage == null) {
- throw new EncryptedDocumentException("opcPackage is null");
- }
- if (uriDereferencer == null) {
- uriDereferencer = new OOXMLURIDereferencer();
- }
- if (uriDereferencer instanceof SignatureConfigurable) {
- ((SignatureConfigurable)uriDereferencer).setSignatureConfig(this);
- }
- if (namespacePrefixes.isEmpty()) {
- /*
- * OOo doesn't like ds namespaces so per default prefixing is off.
- */
- // namespacePrefixes.put(XML_DIGSIG_NS, "");
- namespacePrefixes.put(OO_DIGSIG_NS, "mdssi");
- namespacePrefixes.put(XADES_132_NS, "xd");
- }
-
- if (onlyValidation) {
- return;
- }
-
- if (signatureMarshalListener == null) {
- signatureMarshalListener = new SignatureMarshalListener();
- }
-
- if (signatureMarshalListener instanceof SignatureConfigurable) {
- ((SignatureConfigurable)signatureMarshalListener).setSignatureConfig(this);
- }
-
- if (tspService != null) {
- tspService.setSignatureConfig(this);
- }
-
- if (signatureFacets.isEmpty()) {
- addSignatureFacet(new OOXMLSignatureFacet());
- addSignatureFacet(new KeyInfoSignatureFacet());
- addSignatureFacet(new XAdESSignatureFacet());
- addSignatureFacet(new Office2010SignatureFacet());
- }
-
- for (SignatureFacet sf : signatureFacets) {
- sf.setSignatureConfig(this);
- }
+ public SignatureConfig() {
+ // OOo doesn't like ds namespaces so per default prefixing is off.
+ // namespacePrefixes.put(XML_DIGSIG_NS, "");
+ namespacePrefixes.put(OO_DIGSIG_NS, "mdssi");
+ namespacePrefixes.put(XADES_132_NS, "xd");
}
/**
@@ -249,7 +208,11 @@ public class SignatureConfig {
* @return the list of facets, may be empty when the config object is not initialized
*/
public List<SignatureFacet> getSignatureFacets() {
- return signatureFacets;
+ if (signatureFacets.isEmpty()) {
+ return DEFAULT_FACETS.stream().map(Supplier::get).collect(Collectors.toList());
+ } else {
+ return signatureFacets;
+ }
}
/**
@@ -275,14 +238,22 @@ public class SignatureConfig {
/**
* @return the opc package to be used by this thread, stored as thread-local
+ *
+ * @deprecated in POI 4.1.3 - use {@link SignatureInfo#setOpcPackage(OPCPackage)} instead
*/
+ @Deprecated
+ @Removal(version = "5.0.0")
public OPCPackage getOpcPackage() {
return opcPackage.get();
}
/**
* @param opcPackage the opc package to be handled by this thread, stored as thread-local
+ *
+ * @deprecated in POI 4.1.3 - use {@link SignatureInfo#setOpcPackage(OPCPackage)} instead
*/
+ @Deprecated
+ @Removal(version = "5.0.0")
public void setOpcPackage(OPCPackage opcPackage) {
this.opcPackage.set(opcPackage);
}
@@ -378,14 +349,22 @@ public class SignatureConfig {
/**
* @return the dereferencer used for Reference/@URI attributes, defaults to {@link OOXMLURIDereferencer}
+ *
+ * @deprecated in POI 4.1.3 - use {@link SignatureInfo#getUriDereferencer()} instead
*/
+ @Deprecated
+ @Removal(version = "5.0.0")
public URIDereferencer getUriDereferencer() {
return uriDereferencer;
}
/**
* @param uriDereferencer the dereferencer used for Reference/@URI attributes
+ *
+ * @deprecated in POI 4.1.3 - use {@link SignatureInfo#setUriDereferencer(URIDereferencer)} instead
*/
+ @Deprecated
+ @Removal(version = "5.0.0")
public void setUriDereferencer(URIDereferencer uriDereferencer) {
this.uriDereferencer = uriDereferencer;
}
@@ -753,11 +732,10 @@ public class SignatureConfig {
/**
- * @return the event listener which is active while xml structure for
- * the signature is created.
+ * @return the event listener which is active while xml structure for the signature is created.
* Defaults to {@link SignatureMarshalListener}
*/
- public EventListener getSignatureMarshalListener() {
+ public SignatureMarshalListener getSignatureMarshalListener() {
return signatureMarshalListener;
}
@@ -765,7 +743,7 @@ public class SignatureConfig {
* @param signatureMarshalListener the event listener watching the xml structure
* generation for the signature
*/
- public void setSignatureMarshalListener(EventListener signatureMarshalListener) {
+ public void setSignatureMarshalListener(SignatureMarshalListener signatureMarshalListener) {
this.signatureMarshalListener = signatureMarshalListener;
}
@@ -898,85 +876,91 @@ public class SignatureConfig {
/**
* @param signatureFactory the xml signature factory, saved as thread-local
+ *
+ * @deprecated in POI 4.1.3 - use {@link SignatureInfo#setSignatureFactory(XMLSignatureFactory)}
*/
+ @Deprecated
+ @Removal(version = "5.0.0")
public void setSignatureFactory(XMLSignatureFactory signatureFactory) {
this.signatureFactory.set(signatureFactory);
}
/**
* @return the xml signature factory (thread-local)
+ *
+ * @deprecated in POI 4.1.3 - will be handled by SignatureInfo internally
*/
+ @Deprecated
+ @Removal(version = "5.0.0")
public XMLSignatureFactory getSignatureFactory() {
- XMLSignatureFactory sigFac = signatureFactory.get();
- if (sigFac == null) {
- sigFac = XMLSignatureFactory.getInstance("DOM", getProvider());
- setSignatureFactory(sigFac);
- }
- return sigFac;
+ return signatureFactory.get();
}
/**
* @param keyInfoFactory the key factory, saved as thread-local
+ *
+ * @deprecated in POI 4.1.3 - use {@link SignatureInfo#setKeyInfoFactory(KeyInfoFactory)}
*/
+ @Deprecated
+ @Removal(version = "5.0.0")
public void setKeyInfoFactory(KeyInfoFactory keyInfoFactory) {
this.keyInfoFactory.set(keyInfoFactory);
}
/**
* @return the key factory (thread-local)
+ *
+ * @deprecated in POI 4.1.3 - will be handled by SignatureInfo internally
*/
+ @Deprecated
+ @Removal(version = "5.0.0")
public KeyInfoFactory getKeyInfoFactory() {
- KeyInfoFactory keyFac = keyInfoFactory.get();
- if (keyFac == null) {
- keyFac = KeyInfoFactory.getInstance("DOM", getProvider());
- setKeyInfoFactory(keyFac);
- }
- return keyFac;
+ return keyInfoFactory.get();
+ }
+
+ /**
+ * Helper method to set provider
+ * @param provider the provider
+ * @deprecated in POI 4.1.3 - use {@link SignatureInfo#setProvider(Provider)}
+ */
+ @Internal
+ @Deprecated
+ @Removal(version = "5.0.0")
+ public void setProvider(Provider provider) {
+ this.provider.set(provider);
+ }
+
+ /**
+ * @return the cached provider or null if not set before
+ *
+ * @deprecated in POI 4.1.3 - will be handled by SignatureInfo internally
+ */
+ @Deprecated
+ @Removal(version = "5.0.0")
+ public Provider getProvider() {
+ return provider.get();
}
/**
- * This method tests the existence of xml signature provider in the following order:
- * <ul>
+ * Determine the possible classes for XMLSEC.
+ * The order is
+ * <ol>
* <li>the class pointed to by the system property "jsr105Provider"</li>
* <li>the Santuario xmlsec provider</li>
* <li>the JDK xmlsec provider</li>
- * </ul>
- *
- * For signing the classes are linked against the Santuario xmlsec, so this might
- * only work for validation (not tested).
+ * </ol>
*
- * @return the xml dsig provider
+ * @return a list of possible XMLSEC provider class names
*/
- public Provider getProvider() {
- Provider prov = provider.get();
- if (prov == null) {
- String[] dsigProviderNames = {
- System.getProperty("jsr105Provider"),
- // Santuario xmlsec
- "org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI",
- // JDK xmlsec
- "org.jcp.xml.dsig.internal.dom.XMLDSigRI"
- };
- for (String pn : dsigProviderNames) {
- if (pn == null) {
- continue;
- }
- try {
- prov = (Provider)Class.forName(pn).newInstance();
- break;
- } catch (Exception e) {
- LOG.log(POILogger.DEBUG, "XMLDsig-Provider '"+pn+"' can't be found - trying next.");
- }
- }
- }
-
- if (prov == null) {
- throw new RuntimeException("JRE doesn't support default xml signature provider - set jsr105Provider system property!");
- }
-
- return prov;
+ public static String[] getProviderNames() {
+ // need to check every time, as the system property might have been changed in the meantime
+ String sysProp = System.getProperty("jsr105Provider");
+ return (sysProp == null || "".equals(sysProp))
+ ? new String[]{XMLSEC_SANTUARIO, XMLSEC_JDK}
+ : new String[]{sysProp, XMLSEC_SANTUARIO, XMLSEC_JDK};
}
+
/**
* @return the cannonicalization method for XAdES-XL signing.
* Defaults to <code>EXCLUSIVE</code>
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java
index c4f25f1222..806ab91d65 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java
@@ -31,6 +31,7 @@ import java.io.IOException;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
+import java.security.Provider;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
@@ -38,6 +39,8 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.stream.Stream;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.URIDereferencer;
@@ -52,6 +55,7 @@ import javax.xml.crypto.dsig.XMLObject;
import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMSignContext;
+import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import org.apache.jcp.xml.dsig.internal.dom.DOMReference;
@@ -70,7 +74,6 @@ import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.poifs.crypt.CryptoFunctions;
import org.apache.poi.poifs.crypt.HashAlgorithm;
-import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable;
import org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet;
import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService;
import org.apache.poi.util.POILogFactory;
@@ -84,6 +87,7 @@ import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
+import org.w3c.dom.events.MutationEvent;
/**
@@ -153,20 +157,16 @@ import org.w3c.dom.events.EventTarget;
* <li>and slf4j-api (tested against 1.7.30)</li>
* </ul>
*/
-public class SignatureInfo implements SignatureConfigurable {
+public class SignatureInfo {
private static final POILogger LOG = POILogFactory.getLogger(SignatureInfo.class);
- private static boolean isInitialized;
private SignatureConfig signatureConfig;
-
-
- /**
- * Constructor initializes xml signature environment, if it hasn't been initialized before
- */
- public SignatureInfo() {
- initXmlProvider();
- }
+ private OPCPackage opcPackage;
+ private Provider provider;
+ private XMLSignatureFactory signatureFactory;
+ private KeyInfoFactory keyInfoFactory;
+ private URIDereferencer uriDereferencer;
/**
* @return the signature config
@@ -178,30 +178,45 @@ public class SignatureInfo implements SignatureConfigurable {
/**
* @param signatureConfig the signature config, needs to be set before a SignatureInfo object is used
*/
- @Override
public void setSignatureConfig(SignatureConfig signatureConfig) {
this.signatureConfig = signatureConfig;
}
+ public void setOpcPackage(OPCPackage opcPackage) {
+ this.opcPackage = opcPackage;
+ }
+
+ public OPCPackage getOpcPackage() {
+ return opcPackage;
+ }
+
+ public URIDereferencer getUriDereferencer() {
+ return uriDereferencer;
+ }
+
+ public void setUriDereferencer(URIDereferencer uriDereferencer) {
+ this.uriDereferencer = uriDereferencer;
+ }
+
/**
* @return true, if first signature part is valid
*/
public boolean verifySignature() {
+ initXmlProvider();
// http://www.oracle.com/technetwork/articles/javase/dig-signature-api-140772.html
- for (SignaturePart sp : getSignatureParts()){
- // only validate first part
- return sp.validate();
- }
- return false;
+ // only validate first part
+ Iterator<SignaturePart> iter = getSignatureParts().iterator();
+ return iter.hasNext() && iter.next().validate();
}
/**
* add the xml signature to the document
*
- * @throws XMLSignatureException
- * @throws MarshalException
+ * @throws XMLSignatureException if the signature can't be calculated
+ * @throws MarshalException if the document can't be serialized
*/
public void confirmSignature() throws XMLSignatureException, MarshalException {
+ initXmlProvider();
final Document document = DocumentHelper.createDocument();
final DOMSignContext xmlSignContext = createXMLSignContext(document);
@@ -223,6 +238,7 @@ public class SignatureInfo implements SignatureConfigurable {
* @return the initialized signature context
*/
public DOMSignContext createXMLSignContext(final Document document) {
+ initXmlProvider();
return new DOMSignContext(signatureConfig.getKey(), document);
}
@@ -231,10 +247,10 @@ public class SignatureInfo implements SignatureConfigurable {
* Sign (encrypt) the digest with the private key.
* Currently only rsa is supported.
*
- * @param digest the hashed input
* @return the encrypted hash
*/
public String signDigest(final DOMSignContext xmlSignContext, final DOMSignedInfo signedInfo) {
+ initXmlProvider();
final PrivateKey key = signatureConfig.getKey();
final HashAlgorithm algo = signatureConfig.getDigestAlgo();
@@ -243,12 +259,12 @@ public class SignatureInfo implements SignatureConfigurable {
if (algo.hashSize*4/3 > BASE64DEFAULTLENGTH && !XMLUtils.ignoreLineBreaks()) {
- throw new EncryptedDocumentException("The hash size of the choosen hash algorithm ("+algo+" = "+algo.hashSize+" bytes), "+
+ throw new EncryptedDocumentException("The hash size of the chosen hash algorithm ("+algo+" = "+algo.hashSize+" bytes), "+
"will motivate XmlSec to add linebreaks to the generated digest, which results in an invalid signature (... at least "+
"for Office) - please persuade it otherwise by adding '-Dorg.apache.xml.security.ignoreLineBreaks=true' to the JVM "+
"system properties.");
}
-
+
try (final DigestOutputStream dos = getDigestStream(algo, key)) {
dos.init();
@@ -277,78 +293,61 @@ public class SignatureInfo implements SignatureConfigurable {
* the parts can be validated independently.
*/
public Iterable<SignaturePart> getSignatureParts() {
- signatureConfig.init(true);
- return new Iterable<SignaturePart>() {
- @Override
- public Iterator<SignaturePart> iterator() {
- return new Iterator<SignaturePart>() {
- OPCPackage pkg = signatureConfig.getOpcPackage();
- Iterator<PackageRelationship> sigOrigRels =
- pkg.getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN).iterator();
- Iterator<PackageRelationship> sigRels;
- PackagePart sigPart;
-
- @Override
- public boolean hasNext() {
- while (sigRels == null || !sigRels.hasNext()) {
- if (!sigOrigRels.hasNext()) {
- return false;
- }
- sigPart = pkg.getPart(sigOrigRels.next());
- LOG.log(POILogger.DEBUG, "Digital Signature Origin part", sigPart);
- try {
- sigRels = sigPart.getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE).iterator();
- } catch (InvalidFormatException e) {
- LOG.log(POILogger.WARN, "Reference to signature is invalid.", e);
- }
- }
- return true;
- }
+ initXmlProvider();
+ return SignaturePartIterator::new;
+ }
- @Override
- public SignaturePart next() {
- PackagePart sigRelPart = null;
- do {
- try {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- sigRelPart = sigPart.getRelatedPart(sigRels.next());
- LOG.log(POILogger.DEBUG, "XML Signature part", sigRelPart);
- } catch (InvalidFormatException e) {
- LOG.log(POILogger.WARN, "Reference to signature is invalid.", e);
- }
- } while (sigRelPart == null);
- return new SignaturePart(sigRelPart, signatureConfig);
- }
+ private final class SignaturePartIterator implements Iterator<SignaturePart> {
+ Iterator<PackageRelationship> sigOrigRels;
+ private Iterator<PackageRelationship> sigRels;
+ private PackagePart sigPart;
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
+ private SignaturePartIterator() {
+ sigOrigRels = opcPackage.getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN).iterator();
+ }
+
+ @Override
+ public boolean hasNext() {
+ while (sigRels == null || !sigRels.hasNext()) {
+ if (!sigOrigRels.hasNext()) {
+ return false;
+ }
+ sigPart = opcPackage.getPart(sigOrigRels.next());
+ LOG.log(POILogger.DEBUG, "Digital Signature Origin part", sigPart);
+ try {
+ sigRels = sigPart.getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE).iterator();
+ } catch (InvalidFormatException e) {
+ LOG.log(POILogger.WARN, "Reference to signature is invalid.", e);
+ }
}
- };
- }
+ return true;
+ }
- /**
- * Initialize the xml signing environment and the bouncycastle provider
- */
- protected static synchronized void initXmlProvider() {
- if (isInitialized) {
- return;
+ @Override
+ public SignaturePart next() {
+ PackagePart sigRelPart = null;
+ do {
+ try {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ sigRelPart = sigPart.getRelatedPart(sigRels.next());
+ LOG.log(POILogger.DEBUG, "XML Signature part", sigRelPart);
+ } catch (InvalidFormatException e) {
+ LOG.log(POILogger.WARN, "Reference to signature is invalid.", e);
+ }
+ } while (sigRelPart == null);
+ return new SignaturePart(sigRelPart, SignatureInfo.this);
}
- isInitialized = true;
- try {
- Init.init();
- RelationshipTransformService.registerDsigProvider();
- CryptoFunctions.registerBouncyCastle();
- } catch (Exception e) {
- throw new RuntimeException("Xml & BouncyCastle-Provider initialization failed", e);
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
}
}
+
+
/**
* Helper method for adding informations before the signing.
* Normally {@link #confirmSignature()} is sufficient to be used.
@@ -356,35 +355,18 @@ public class SignatureInfo implements SignatureConfigurable {
@SuppressWarnings("unchecked")
public DOMSignedInfo preSign(final DOMSignContext xmlSignContext)
throws XMLSignatureException, MarshalException {
- signatureConfig.init(false);
-
final Document document = (Document)xmlSignContext.getParent();
- // it's necessary to explicitly set the mdssi namespace, but the sign() method has no
- // normal way to interfere with, so we need to add the namespace under the hand ...
- EventTarget target = (EventTarget)document;
- EventListener creationListener = signatureConfig.getSignatureMarshalListener();
- if (creationListener != null) {
- if (creationListener instanceof SignatureMarshalListener) {
- ((SignatureMarshalListener)creationListener).setEventTarget(target);
- }
- SignatureMarshalListener.setListener(target, creationListener, true);
- }
+ registerEventListener(document);
- /*
- * Signature context construction.
- */
- URIDereferencer uriDereferencer = signatureConfig.getUriDereferencer();
- if (null != uriDereferencer) {
+ // Signature context construction.
+ if (uriDereferencer != null) {
xmlSignContext.setURIDereferencer(uriDereferencer);
}
signatureConfig.getNamespacePrefixes().forEach(xmlSignContext::putNamespacePrefix);
xmlSignContext.setDefaultNamespacePrefix("");
- // signatureConfig.getNamespacePrefixes().get(XML_DIGSIG_NS));
-
- XMLSignatureFactory signatureFactory = signatureConfig.getSignatureFactory();
/*
* Add ds:References that come from signing client local files.
@@ -397,7 +379,7 @@ public class SignatureInfo implements SignatureConfigurable {
List<XMLObject> objects = new ArrayList<>();
for (SignatureFacet signatureFacet : signatureConfig.getSignatureFacets()) {
LOG.log(POILogger.DEBUG, "invoking signature facet: " + signatureFacet.getClass().getSimpleName());
- signatureFacet.preSign(document, references, objects);
+ signatureFacet.preSign(this, document, references, objects);
}
/*
@@ -471,6 +453,35 @@ public class SignatureInfo implements SignatureConfigurable {
return (DOMSignedInfo)signedInfo;
}
+ // it's necessary to explicitly set the mdssi namespace, but the sign() method has no
+ // normal way to interfere with, so we need to add the namespace under the hand ...
+ protected void registerEventListener(Document document) {
+ final SignatureMarshalListener sml = signatureConfig.getSignatureMarshalListener();
+ if (sml == null) {
+ return;
+ }
+
+ EventTarget target = (EventTarget)document;
+
+ final EventListener[] el = { null };
+ el[0] = (e) -> {
+ if (!(e instanceof MutationEvent)) {
+ return;
+ }
+
+ MutationEvent mutEvt = (MutationEvent) e;
+ EventTarget et = mutEvt.getTarget();
+ if (!(et instanceof Element)) {
+ return;
+ }
+
+ sml.handleElement(this, (Element) et, target, el[0]);
+ };
+
+ SignatureMarshalListener.setListener(target, el[0], true);
+ }
+
+
/**
* Helper method for adding informations after the signing.
* Normally {@link #confirmSignature()} is sufficient to be used.
@@ -492,7 +503,7 @@ public class SignatureInfo implements SignatureConfigurable {
/*
* Insert signature value into the ds:SignatureValue element
*/
- final Element signatureNode = getDsigElement(document, "SignatureValue");
+ final Element signatureNode = getDsigElement(document, "SignatureValue");
if (signatureNode == null) {
throw new RuntimeException("preSign has to be called before postSign");
}
@@ -502,7 +513,7 @@ public class SignatureInfo implements SignatureConfigurable {
* Allow signature facets to inject their own stuff.
*/
for (SignatureFacet signatureFacet : signatureConfig.getSignatureFacets()) {
- signatureFacet.postSign(document);
+ signatureFacet.postSign(this, document);
}
writeDocument(document);
@@ -512,7 +523,7 @@ public class SignatureInfo implements SignatureConfigurable {
* Write XML signature into the OPC package
*
* @param document the xml signature document
- * @throws MarshalException
+ * @throws MarshalException if the document can't be serialized
*/
protected void writeDocument(Document document) throws MarshalException {
XmlOptions xo = new XmlOptions();
@@ -527,23 +538,21 @@ public class SignatureInfo implements SignatureConfigurable {
* Copy the original OOXML content to the signed OOXML package. During
* copying some files need to changed.
*/
- OPCPackage pkg = signatureConfig.getOpcPackage();
-
try {
// <Default Extension="sigs" ContentType="application/vnd.openxmlformats-package.digital-signature-origin"/>
final DSigRelation originDesc = DSigRelation.ORIGIN_SIGS;
PackagePartName originPartName = PackagingURIHelper.createPartName(originDesc.getFileName(0));
- PackagePart originPart = pkg.getPart(originPartName);
+ PackagePart originPart = opcPackage.getPart(originPartName);
if (originPart == null) {
// touch empty marker file
- originPart = pkg.createPart(originPartName, originDesc.getContentType());
- pkg.addRelationship(originPartName, TargetMode.INTERNAL, originDesc.getRelation());
+ originPart = opcPackage.createPart(originPartName, originDesc.getContentType());
+ opcPackage.addRelationship(originPartName, TargetMode.INTERNAL, originDesc.getRelation());
}
// <Override PartName="/_xmlsignatures/sig1.xml" ContentType="application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml"/>
final DSigRelation sigDesc = DSigRelation.SIG;
- int nextSigIdx = pkg.getUnusedPartIndex(sigDesc.getDefaultFileName());
+ int nextSigIdx = opcPackage.getUnusedPartIndex(sigDesc.getDefaultFileName());
if (!signatureConfig.isAllowMultipleSignatures()) {
PackageRelationshipCollection prc = originPart.getRelationshipsByType(sigDesc.getRelation());
@@ -558,16 +567,16 @@ public class SignatureInfo implements SignatureConfigurable {
}
}
- pkg.removePart(pkg.getPart(pn));
+ opcPackage.removePart(opcPackage.getPart(pn));
}
nextSigIdx = 1;
}
PackagePartName sigPartName = PackagingURIHelper.createPartName(sigDesc.getFileName(nextSigIdx));
- PackagePart sigPart = pkg.getPart(sigPartName);
+ PackagePart sigPart = opcPackage.getPart(sigPartName);
if (sigPart == null) {
- sigPart = pkg.createPart(sigPartName, sigDesc.getContentType());
+ sigPart = opcPackage.createPart(sigPartName, sigDesc.getContentType());
originPart.addRelationship(sigPartName, TargetMode.INTERNAL, sigDesc.getRelation());
} else {
sigPart.clear();
@@ -590,7 +599,123 @@ public class SignatureInfo implements SignatureConfigurable {
}
LOG.log(POILogger.WARN, "Signature element '"+localName+"' was "+(sigValNl.getLength() == 0 ? "not found" : "multiple times"));
-
+
return null;
}
+
+ public void setProvider(Provider provider) {
+ this.provider = provider;
+ }
+
+ public void setSignatureFactory(XMLSignatureFactory signatureFactory) {
+ this.signatureFactory = signatureFactory;
+ }
+
+ public XMLSignatureFactory getSignatureFactory() {
+ return signatureFactory;
+ }
+
+ public void setKeyInfoFactory(KeyInfoFactory keyInfoFactory) {
+ this.keyInfoFactory = keyInfoFactory;
+ }
+
+ public KeyInfoFactory getKeyInfoFactory() {
+ return keyInfoFactory;
+ }
+
+
+
+ /**
+ * Initialize the xml signing environment and the bouncycastle provider
+ */
+ @SuppressWarnings("deprecation")
+ protected void initXmlProvider() {
+ if (opcPackage == null) {
+ opcPackage = signatureConfig.getOpcPackage();
+ }
+ if (provider == null) {
+ provider = signatureConfig.getProvider();
+ if (provider == null) {
+ provider = XmlProviderInitSingleton.getInstance().findProvider();
+ }
+ }
+ if (signatureFactory == null) {
+ signatureFactory = signatureConfig.getSignatureFactory();
+ if (signatureFactory == null) {
+ signatureFactory = XMLSignatureFactory.getInstance("DOM", provider);
+ }
+ }
+ if (keyInfoFactory == null) {
+ keyInfoFactory = signatureConfig.getKeyInfoFactory();
+ if (keyInfoFactory == null) {
+ keyInfoFactory = KeyInfoFactory.getInstance("DOM", provider);
+ }
+ }
+ if (uriDereferencer == null) {
+ uriDereferencer = signatureConfig.getUriDereferencer();
+ if (uriDereferencer == null) {
+ uriDereferencer = new OOXMLURIDereferencer();
+ }
+ }
+ if (uriDereferencer instanceof OOXMLURIDereferencer) {
+ ((OOXMLURIDereferencer)uriDereferencer).setSignatureInfo(this);
+ }
+ }
+
+ private static final class XmlProviderInitSingleton {
+
+ // Bill Pugh Singleton
+ private static class SingletonHelper {
+ private static final XmlProviderInitSingleton INSTANCE = new XmlProviderInitSingleton();
+ }
+
+ public static XmlProviderInitSingleton getInstance(){
+ return SingletonHelper.INSTANCE;
+ }
+
+ private XmlProviderInitSingleton() {
+ try {
+ Init.init();
+ RelationshipTransformService.registerDsigProvider();
+ CryptoFunctions.registerBouncyCastle();
+ } catch (Exception e) {
+ throw new RuntimeException("Xml & BouncyCastle-Provider initialization failed", e);
+ }
+ }
+
+ /**
+ * This method tests the existence of xml signature provider in the following order:
+ * <ul>
+ * <li>the class pointed to by the system property "jsr105Provider"</li>
+ * <li>the Santuario xmlsec provider</li>
+ * <li>the JDK xmlsec provider</li>
+ * </ul>
+ *
+ * For signing the classes are linked against the Santuario xmlsec, so this might
+ * only work for validation (not tested).
+ *
+ * @return the xml dsig provider
+ */
+ public Provider findProvider() {
+ return
+ Stream.of(SignatureConfig.getProviderNames())
+ .map(this::getProvider)
+ .filter(Objects::nonNull).findFirst()
+ .orElseThrow(this::providerNotFound);
+ }
+
+ private Provider getProvider(String className) {
+ try {
+ return (Provider)Class.forName(className).newInstance();
+ } catch (Exception e) {
+ LOG.log(POILogger.DEBUG, "XMLDsig-Provider '"+className+"' can't be found - trying next.");
+ return null;
+ }
+ }
+
+ private RuntimeException providerNotFound() {
+ return new RuntimeException("JRE doesn't support default xml signature provider - set jsr105Provider system property!");
+ }
+ }
+
}
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureMarshalDefaultListener.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureMarshalDefaultListener.java
new file mode 100644
index 0000000000..24acda22ed
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureMarshalDefaultListener.java
@@ -0,0 +1,63 @@
+/* ====================================================================
+ 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 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_NS;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.events.EventListener;
+import org.w3c.dom.events.EventTarget;
+
+/**
+ * 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
+ */
+public class SignatureMarshalDefaultListener implements SignatureMarshalListener {
+ @Override
+ public void handleElement(SignatureInfo signatureInfo, Element el, EventTarget target, EventListener parentListener) {
+ if (el.hasAttribute("Id")) {
+ el.setIdAttribute("Id", true);
+ }
+
+ 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);
+ }
+ }
+ 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);
+ }
+
+ NodeList nl = el.getChildNodes();
+ for (int i=0; i<nl.getLength(); i++) {
+ setPrefix(signatureInfo, nl.item(i));
+ }
+ }
+}
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureMarshalListener.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureMarshalListener.java
index 017953f570..34210f4cf5 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureMarshalListener.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureMarshalListener.java
@@ -17,85 +17,25 @@
package org.apache.poi.poifs.crypt.dsig;
-import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.OO_DIGSIG_NS;
-import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.XML_NS;
-
-import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable;
import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
-import org.w3c.dom.events.MutationEvent;
/**
- * This listener class is used, to modify the to be digested xml document,
+ * This listener interface is used, to modify the to be digested xml document,
* e.g. to register id attributes or set prefixes for registered namespaces
*/
-public class SignatureMarshalListener implements EventListener, SignatureConfigurable {
- ThreadLocal<EventTarget> target = new ThreadLocal<>();
- SignatureConfig signatureConfig;
- public void setEventTarget(EventTarget target) {
- this.target.set(target);
- }
-
- @Override
- public void handleEvent(Event e) {
- if (!(e instanceof MutationEvent)) {
- return;
- }
- MutationEvent mutEvt = (MutationEvent)e;
- EventTarget et = mutEvt.getTarget();
- if (!(et instanceof Element)) {
- return;
- }
- handleElement((Element)et);
- }
-
- public void handleElement(Element el) {
- EventTarget target = this.target.get();
-
- if (el.hasAttribute("Id")) {
- el.setIdAttribute("Id", true);
- }
-
- setListener(target, this, 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);
- }
- }
- setPrefix(el);
- setListener(target, this, true);
- }
+public interface SignatureMarshalListener {
+ void handleElement(SignatureInfo signatureInfo, Element el, EventTarget target, EventListener parentListener);
// helper method to keep it in one place
- public static void setListener(EventTarget target, EventListener listener, boolean enabled) {
- String type = "DOMSubtreeModified";
- boolean useCapture = false;
+ 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, useCapture);
+ target.addEventListener(type, listener, DONT_USE_CAPTURE);
} else {
- target.removeEventListener(type, listener, useCapture);
+ target.removeEventListener(type, listener, DONT_USE_CAPTURE);
}
}
-
- protected void setPrefix(Node el) {
- String prefix = signatureConfig.getNamespacePrefixes().get(el.getNamespaceURI());
- if (prefix != null && el.getPrefix() == null) {
- el.setPrefix(prefix);
- }
-
- NodeList nl = el.getChildNodes();
- for (int i=0; i<nl.getLength(); i++) {
- setPrefix(nl.item(i));
- }
- }
-
- @Override
- public void setSignatureConfig(SignatureConfig signatureConfig) {
- this.signatureConfig = signatureConfig;
- }
} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignaturePart.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignaturePart.java
index dab69bd250..d120d655e1 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignaturePart.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignaturePart.java
@@ -30,6 +30,7 @@ import java.util.Map;
import java.util.function.Consumer;
import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.URIDereferencer;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.crypto.dsig.XMLSignatureFactory;
@@ -54,40 +55,40 @@ import org.xml.sax.SAXException;
public class SignaturePart {
private static final POILogger LOG = POILogFactory.getLogger(SignaturePart.class);
- private static final String XMLSEC_VALIDATE_MANIFEST = "org.jcp.xml.dsig.validateManifests";
+ private static final String XMLSEC_VALIDATE_MANIFEST = "org.jcp.xml.dsig.validateManifests";
+
-
private final PackagePart signaturePart;
- private final SignatureConfig signatureConfig;
+ private final SignatureInfo signatureInfo;
private X509Certificate signer;
private List<X509Certificate> certChain;
-
- /* package */ SignaturePart(final PackagePart signaturePart, final SignatureConfig signatureConfig) {
+
+ /* package */ SignaturePart(final PackagePart signaturePart, final SignatureInfo signatureInfo) {
this.signaturePart = signaturePart;
- this.signatureConfig = signatureConfig;
+ this.signatureInfo = signatureInfo;
}
-
+
/**
* @return the package part containing the signature
*/
public PackagePart getPackagePart() {
return signaturePart;
}
-
+
/**
* @return the signer certificate
*/
public X509Certificate getSigner() {
return signer;
}
-
+
/**
* @return the certificate chain of the signer
*/
public List<X509Certificate> getCertChain() {
return certChain;
}
-
+
/**
* Helper method for examining the xml signature
*
@@ -102,7 +103,7 @@ public class SignaturePart {
/**
* @return true, when the xml signature is valid, false otherwise
- *
+ *
* @throws EncryptedDocumentException if the signature can't be extracted or if its malformed
*/
public boolean validate() {
@@ -117,14 +118,16 @@ public class SignaturePart {
for (int i=0; i<length; i++) {
((Element)nl.item(i)).setIdAttribute("Id", true);
}
-
+
DOMValidateContext domValidateContext = new DOMValidateContext(keySelector, doc);
domValidateContext.setProperty(XMLSEC_VALIDATE_MANIFEST, Boolean.TRUE);
- domValidateContext.setURIDereferencer(signatureConfig.getUriDereferencer());
- XMLSignatureFactory xmlSignatureFactory = signatureConfig.getSignatureFactory();
+ URIDereferencer uriDereferencer = signatureInfo.getUriDereferencer();
+ domValidateContext.setURIDereferencer(uriDereferencer);
+
+ XMLSignatureFactory xmlSignatureFactory = signatureInfo.getSignatureFactory();
XMLSignature xmlSignature = xmlSignatureFactory.unmarshalXMLSignature(domValidateContext);
-
+
boolean valid = xmlSignature.validate(domValidateContext);
if (valid) {
@@ -132,7 +135,7 @@ public class SignaturePart {
certChain = keySelector.getCertChain();
extractConfig(doc, xmlSignature);
}
-
+
return valid;
} catch (IOException e) {
String s = "error in reading document";
@@ -158,6 +161,7 @@ public class SignaturePart {
}
private void extractConfig(final Document doc, final XMLSignature xmlSignature) throws XPathExpressionException {
+ SignatureConfig signatureConfig = signatureInfo.getSignatureConfig();
if (!signatureConfig.isUpdateConfigOnValidate()) {
return;
}
@@ -168,7 +172,7 @@ public class SignaturePart {
final XPath xpath = XPathHelper.getFactory().newXPath();
xpath.setNamespaceContext(new XPathNSContext());
- final Map<String,Consumer<String>> m = new HashMap();
+ final Map<String,Consumer<String>> m = new HashMap<>();
m.put("//mdssi:SignatureTime/mdssi:Value", signatureConfig::setExecutionTime);
m.put("//xd:ClaimedRole", signatureConfig::setXadesRole);
m.put("//dsss:SignatureComments", signatureConfig::setSignatureDescription);
@@ -185,7 +189,7 @@ public class SignaturePart {
final Map<String,String> nsMap = new HashMap<>();
{
- signatureConfig.getNamespacePrefixes().forEach((k,v) -> nsMap.put(v,k));
+ signatureInfo.getSignatureConfig().getNamespacePrefixes().forEach((k,v) -> nsMap.put(v,k));
nsMap.put("dsss", MS_DIGSIG_NS);
nsMap.put("ds", XML_DIGSIG_NS);
}
@@ -193,6 +197,8 @@ public class SignaturePart {
public String getNamespaceURI(String prefix) {
return nsMap.get(prefix);
}
+ @SuppressWarnings("rawtypes")
+ @Override
public Iterator getPrefixes(String val) {
return null;
}
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/EnvelopedSignatureFacet.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/EnvelopedSignatureFacet.java
index 12ba42c14c..d37cc2ce77 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/EnvelopedSignatureFacet.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/EnvelopedSignatureFacet.java
@@ -18,12 +18,15 @@
/* ====================================================================
This product contains an ASLv2 licensed version of the OOXML signer
package from the eID Applet project
- http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
Copyright (C) 2008-2014 FedICT.
- ================================================================= */
+ ================================================================= */
package org.apache.poi.poifs.crypt.dsig.facets;
+import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacetHelper.newReference;
+import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacetHelper.newTransform;
+
import java.util.ArrayList;
import java.util.List;
@@ -33,28 +36,29 @@ import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLObject;
import javax.xml.crypto.dsig.XMLSignatureException;
+import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.w3c.dom.Document;
/**
* Signature Facet implementation to create enveloped signatures.
- *
+ *
* @author Frank Cornelis
- *
*/
-public class EnvelopedSignatureFacet extends SignatureFacet {
+public class EnvelopedSignatureFacet implements SignatureFacet {
@Override
- public void preSign(Document document
+ public void preSign(SignatureInfo signatureInfo
+ , Document document
, List<Reference> references
, List<XMLObject> objects)
throws XMLSignatureException {
List<Transform> transforms = new ArrayList<>();
- Transform envelopedTransform = newTransform(CanonicalizationMethod.ENVELOPED);
+ Transform envelopedTransform = newTransform(signatureInfo, CanonicalizationMethod.ENVELOPED);
transforms.add(envelopedTransform);
- Transform exclusiveTransform = newTransform(CanonicalizationMethod.EXCLUSIVE);
+ Transform exclusiveTransform = newTransform(signatureInfo, CanonicalizationMethod.EXCLUSIVE);
transforms.add(exclusiveTransform);
- Reference reference = newReference("", transforms, null, null, null);
+ Reference reference = newReference(signatureInfo, "", transforms, null, null, null);
references.add(reference);
}
}
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/KeyInfoSignatureFacet.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/KeyInfoSignatureFacet.java
index e7797e942d..0943a8a596 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/KeyInfoSignatureFacet.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/KeyInfoSignatureFacet.java
@@ -18,9 +18,9 @@
/* ====================================================================
This product contains an ASLv2 licensed version of the OOXML signer
package from the eID Applet project
- http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
Copyright (C) 2008-2014 FedICT.
- ================================================================= */
+ ================================================================= */
package org.apache.poi.poifs.crypt.dsig.facets;
@@ -29,7 +29,6 @@ import java.security.KeyException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.XMLStructure;
@@ -41,6 +40,8 @@ import javax.xml.crypto.dsig.keyinfo.KeyValue;
import javax.xml.crypto.dsig.keyinfo.X509Data;
import org.apache.jcp.xml.dsig.internal.dom.DOMKeyInfo;
+import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
+import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.w3c.dom.Document;
@@ -50,21 +51,20 @@ import org.w3c.dom.NodeList;
/**
* Signature Facet implementation that adds ds:KeyInfo to the XML signature.
- *
+ *
* @author Frank Cornelis
- *
*/
-public class KeyInfoSignatureFacet extends SignatureFacet {
+public class KeyInfoSignatureFacet implements SignatureFacet {
private static final POILogger LOG = POILogFactory.getLogger(KeyInfoSignatureFacet.class);
-
+
@Override
- public void postSign(Document document)
+ public void postSign(SignatureInfo signatureInfo, Document document)
throws MarshalException {
LOG.log(POILogger.DEBUG, "postSign");
NodeList nl = document.getElementsByTagNameNS(XML_DIGSIG_NS, "Object");
-
+
/*
* Make sure we insert right after the ds:SignatureValue element, just
* before the first ds:Object element.
@@ -74,8 +74,9 @@ public class KeyInfoSignatureFacet extends SignatureFacet {
/*
* Construct the ds:KeyInfo element using JSR 105.
*/
- KeyInfoFactory keyInfoFactory = signatureConfig.getKeyInfoFactory();
+ KeyInfoFactory keyInfoFactory = signatureInfo.getKeyInfoFactory();
List<Object> x509DataObjects = new ArrayList<>();
+ SignatureConfig signatureConfig = signatureInfo.getSignatureConfig();
X509Certificate signingCertificate = signatureConfig.getSigningCertificateChain().get(0);
List<XMLStructure> keyInfoContent = new ArrayList<>();
@@ -107,7 +108,7 @@ public class KeyInfoSignatureFacet extends SignatureFacet {
keyInfoContent.add(x509Data);
}
KeyInfo keyInfo = keyInfoFactory.newKeyInfo(keyInfoContent);
- DOMKeyInfo domKeyInfo = (DOMKeyInfo)keyInfo;
+ DOMKeyInfo domKeyInfo = (DOMKeyInfo)keyInfo;
Key key = new Key() {
private static final long serialVersionUID = 1L;
@@ -133,7 +134,7 @@ public class KeyInfoSignatureFacet extends SignatureFacet {
DOMStructure domStructure = new DOMStructure(n);
domKeyInfo.marshal(domStructure, domSignContext);
-
+
// move keyinfo into the right place
if (nextSibling != null) {
NodeList kiNl = document.getElementsByTagNameNS(XML_DIGSIG_NS, "KeyInfo");
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/OOXMLSignatureFacet.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/OOXMLSignatureFacet.java
index 5d4ccbd869..0eff7e3186 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/OOXMLSignatureFacet.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/OOXMLSignatureFacet.java
@@ -24,20 +24,21 @@
package org.apache.poi.poifs.crypt.dsig.facets;
+import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacetHelper.newReference;
+import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacetHelper.newTransform;
+
import java.net.URI;
import java.net.URISyntaxException;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
-import java.util.Locale;
import java.util.Set;
import javax.xml.XMLConstants;
+import javax.xml.crypto.URIReference;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dom.DOMStructure;
import javax.xml.crypto.dsig.CanonicalizationMethod;
@@ -48,7 +49,10 @@ import javax.xml.crypto.dsig.SignatureProperty;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLObject;
import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import com.microsoft.schemas.office.x2006.digsig.CTSignatureInfoV1;
+import com.microsoft.schemas.office.x2006.digsig.SignatureInfoV1Document;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.ContentTypes;
import org.apache.poi.openxml4j.opc.OPCPackage;
@@ -58,9 +62,10 @@ import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.TargetMode;
+import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
+import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService;
import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService.RelationshipTransformParameterSpec;
-import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.openxmlformats.schemas.xpackage.x2006.digitalSignature.CTSignatureTime;
@@ -68,58 +73,58 @@ import org.openxmlformats.schemas.xpackage.x2006.digitalSignature.SignatureTimeD
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.microsoft.schemas.office.x2006.digsig.CTSignatureInfoV1;
-import com.microsoft.schemas.office.x2006.digsig.SignatureInfoV1Document;
-
/**
* Office OpenXML Signature Facet implementation.
*
* @see <a href="http://msdn.microsoft.com/en-us/library/cc313071.aspx">[MS-OFFCRYPTO]: Office Document Cryptography Structure</a>
*/
-public class OOXMLSignatureFacet extends SignatureFacet {
+public class OOXMLSignatureFacet implements SignatureFacet {
private static final POILogger LOG = POILogFactory.getLogger(OOXMLSignatureFacet.class);
private static final String ID_PACKAGE_OBJECT = "idPackageObject";
@Override
public void preSign(
- Document document
+ SignatureInfo signatureInfo
+ , Document document
, List<Reference> references
, List<XMLObject> objects)
throws XMLSignatureException {
LOG.log(POILogger.DEBUG, "pre sign");
- addManifestObject(document, references, objects);
- addSignatureInfo(document, references, objects);
+ addManifestObject(signatureInfo, document, references, objects);
+ addSignatureInfo(signatureInfo, document, references, objects);
}
protected void addManifestObject(
- Document document
+ SignatureInfo signatureInfo
+ , Document document
, List<Reference> references
, List<XMLObject> objects)
throws XMLSignatureException {
+ final XMLSignatureFactory sigFac = signatureInfo.getSignatureFactory();
+
List<Reference> manifestReferences = new ArrayList<>();
- addManifestReferences(manifestReferences);
- Manifest manifest = getSignatureFactory().newManifest(manifestReferences);
+ addManifestReferences(signatureInfo, manifestReferences);
+ Manifest manifest = sigFac.newManifest(manifestReferences);
List<XMLStructure> objectContent = new ArrayList<>();
objectContent.add(manifest);
- addSignatureTime(document, objectContent);
+ addSignatureTime(signatureInfo, document, objectContent);
- XMLObject xo = getSignatureFactory().newXMLObject(objectContent, ID_PACKAGE_OBJECT, null, null);
+ XMLObject xo = sigFac.newXMLObject(objectContent, ID_PACKAGE_OBJECT, null, null);
objects.add(xo);
- Reference reference = newReference("#"+ID_PACKAGE_OBJECT, null, XML_DIGSIG_NS+"Object", null, null);
+ Reference reference = newReference(signatureInfo, "#"+ID_PACKAGE_OBJECT, null, XML_DIGSIG_NS+"Object", null, null);
references.add(reference);
}
@SuppressWarnings("resource")
- protected void addManifestReferences(List<Reference> manifestReferences)
+ protected void addManifestReferences(SignatureInfo signatureInfo, List<Reference> manifestReferences)
throws XMLSignatureException {
-
- OPCPackage ooxml = signatureConfig.getOpcPackage();
- List<PackagePart> relsEntryNames = ooxml.getPartsByContentType(ContentTypes.RELATIONSHIPS_PART);
+ OPCPackage opcPackage = signatureInfo.getOpcPackage();
+ List<PackagePart> relsEntryNames = opcPackage.getPartsByContentType(ContentTypes.RELATIONSHIPS_PART);
Set<String> digestedPartNames = new HashSet<>();
for (PackagePart pp : relsEntryNames) {
@@ -127,7 +132,7 @@ public class OOXMLSignatureFacet extends SignatureFacet {
PackageRelationshipCollection prc;
try {
- prc = new PackageRelationshipCollection(ooxml);
+ prc = new PackageRelationshipCollection(opcPackage);
prc.parseRelationshipsPart(pp);
} catch (InvalidFormatException e) {
throw new XMLSignatureException("Invalid relationship descriptor: "+pp.getPartName().getName(), e);
@@ -163,7 +168,7 @@ public class OOXMLSignatureFacet extends SignatureFacet {
String contentType;
try {
PackagePartName relName = PackagingURIHelper.createPartName(partName);
- PackagePart pp2 = ooxml.getPart(relName);
+ PackagePart pp2 = opcPackage.getPart(relName);
contentType = pp2.getContentType();
} catch (InvalidFormatException e) {
throw new XMLSignatureException(e);
@@ -176,26 +181,22 @@ public class OOXMLSignatureFacet extends SignatureFacet {
}
String uri = partName + "?ContentType=" + contentType;
- Reference reference = newReference(uri, null, null, null, null);
+ Reference reference = newReference(signatureInfo, uri, null, null, null, null);
manifestReferences.add(reference);
}
if (parameterSpec.hasSourceIds()) {
List<Transform> transforms = new ArrayList<>();
- transforms.add(newTransform(RelationshipTransformService.TRANSFORM_URI, parameterSpec));
- transforms.add(newTransform(CanonicalizationMethod.INCLUSIVE));
+ transforms.add(newTransform(signatureInfo, RelationshipTransformService.TRANSFORM_URI, parameterSpec));
+ transforms.add(newTransform(signatureInfo, CanonicalizationMethod.INCLUSIVE));
String uri = normalizePartName(pp.getPartName().getURI(), baseUri)
+ "?ContentType=application/vnd.openxmlformats-package.relationships+xml";
- Reference reference = newReference(uri, transforms, null, null, null);
+ Reference reference = newReference(signatureInfo, uri, transforms, null, null, null);
manifestReferences.add(reference);
}
}
-
- manifestReferences.sort(new Comparator<Reference>() {
- public int compare(Reference o1, Reference o2) {
- return o1.getURI().compareTo(o2.getURI());
- }
- });
+
+ manifestReferences.sort(Comparator.comparing(URIReference::getURI));
}
/**
@@ -217,7 +218,9 @@ public class OOXMLSignatureFacet extends SignatureFacet {
}
- protected void addSignatureTime(Document document, List<XMLStructure> objectContent) {
+ protected void addSignatureTime(SignatureInfo signatureInfo, Document document, List<XMLStructure> objectContent) {
+ SignatureConfig signatureConfig = signatureInfo.getSignatureConfig();
+ XMLSignatureFactory sigFac = signatureInfo.getSignatureFactory();
/*
* SignatureTime
*/
@@ -230,20 +233,25 @@ public class OOXMLSignatureFacet extends SignatureFacet {
Element n = (Element)document.importNode(ctTime.getDomNode(),true);
List<XMLStructure> signatureTimeContent = new ArrayList<>();
signatureTimeContent.add(new DOMStructure(n));
- SignatureProperty signatureTimeSignatureProperty = getSignatureFactory()
+ SignatureProperty signatureTimeSignatureProperty = sigFac
.newSignatureProperty(signatureTimeContent, "#" + signatureConfig.getPackageSignatureId(),
"idSignatureTime");
List<SignatureProperty> signaturePropertyContent = new ArrayList<>();
signaturePropertyContent.add(signatureTimeSignatureProperty);
- SignatureProperties signatureProperties = getSignatureFactory()
+ SignatureProperties signatureProperties = sigFac
.newSignatureProperties(signaturePropertyContent, null);
objectContent.add(signatureProperties);
}
- protected void addSignatureInfo(Document document,
- List<Reference> references,
- List<XMLObject> objects)
+ protected void addSignatureInfo(
+ SignatureInfo signatureInfo
+ , Document document
+ , List<Reference> references
+ , List<XMLObject> objects)
throws XMLSignatureException {
+ SignatureConfig signatureConfig = signatureInfo.getSignatureConfig();
+ XMLSignatureFactory sigFac = signatureInfo.getSignatureFactory();
+
List<XMLStructure> objectContent = new ArrayList<>();
SignatureInfoV1Document sigV1 = SignatureInfoV1Document.Factory.newInstance();
@@ -259,20 +267,20 @@ public class OOXMLSignatureFacet extends SignatureFacet {
List<XMLStructure> signatureInfoContent = new ArrayList<>();
signatureInfoContent.add(new DOMStructure(n));
- SignatureProperty signatureInfoSignatureProperty = getSignatureFactory()
+ SignatureProperty signatureInfoSignatureProperty = sigFac
.newSignatureProperty(signatureInfoContent, "#" + signatureConfig.getPackageSignatureId(),
"idOfficeV1Details");
List<SignatureProperty> signaturePropertyContent = new ArrayList<>();
signaturePropertyContent.add(signatureInfoSignatureProperty);
- SignatureProperties signatureProperties = getSignatureFactory()
+ SignatureProperties signatureProperties = sigFac
.newSignatureProperties(signaturePropertyContent, null);
objectContent.add(signatureProperties);
String objectId = "idOfficeObject";
- objects.add(getSignatureFactory().newXMLObject(objectContent, objectId, null, null));
+ objects.add(sigFac.newXMLObject(objectContent, objectId, null, null));
- Reference reference = newReference("#" + objectId, null, XML_DIGSIG_NS+"Object", null, null);
+ Reference reference = newReference(signatureInfo, "#" + objectId, null, XML_DIGSIG_NS+"Object", null, null);
references.add(reference);
}
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/Office2010SignatureFacet.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/Office2010SignatureFacet.java
index 59ba63c3da..f9ea3a9662 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/Office2010SignatureFacet.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/Office2010SignatureFacet.java
@@ -18,9 +18,9 @@
/* ====================================================================
This product contains an ASLv2 licensed version of the OOXML signer
package from the eID Applet project
- http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
Copyright (C) 2008-2014 FedICT.
- ================================================================= */
+ ================================================================= */
package org.apache.poi.poifs.crypt.dsig.facets;
@@ -28,6 +28,7 @@ import static org.apache.poi.ooxml.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
import javax.xml.crypto.MarshalException;
+import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.apache.xmlbeans.XmlException;
import org.etsi.uri.x01903.v13.QualifyingPropertiesType;
import org.etsi.uri.x01903.v13.UnsignedPropertiesType;
@@ -38,17 +39,15 @@ import org.w3c.dom.NodeList;
/**
* Work-around for Office2010 to accept the XAdES-BES/EPES signature.
- *
- * xades:UnsignedProperties/xades:UnsignedSignatureProperties needs to be
- * present.
- *
+ *
+ * xades:UnsignedProperties/xades:UnsignedSignatureProperties needs to be present.
+ *
* @author Frank Cornelis
- *
*/
-public class Office2010SignatureFacet extends SignatureFacet {
+public class Office2010SignatureFacet implements SignatureFacet {
@Override
- public void postSign(Document document)
+ public void postSign(SignatureInfo signatureInfo, Document document)
throws MarshalException {
// check for XAdES-BES
NodeList nl = document.getElementsByTagNameNS(XADES_132_NS, "QualifyingProperties");
@@ -62,7 +61,7 @@ public class Office2010SignatureFacet extends SignatureFacet {
} catch (XmlException e) {
throw new MarshalException(e);
}
-
+
// create basic XML container structure
UnsignedPropertiesType unsignedProps = qualProps.getUnsignedProperties();
if (unsignedProps == null) {
@@ -72,7 +71,7 @@ public class Office2010SignatureFacet extends SignatureFacet {
if (unsignedSigProps == null) {
/* unsignedSigProps = */ unsignedProps.addNewUnsignedSignatureProperties();
}
-
+
Node n = document.importNode(qualProps.getDomNode().getFirstChild(), true);
nl.item(0).getParentNode().replaceChild(n, nl.item(0));
}
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/SignatureFacet.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/SignatureFacet.java
index 29852f0044..cc1a803ce6 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/SignatureFacet.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/SignatureFacet.java
@@ -18,70 +18,57 @@
/* ====================================================================
This product contains an ASLv2 licensed version of the OOXML signer
package from the eID Applet project
- http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
Copyright (C) 2008-2014 FedICT.
- ================================================================= */
+ ================================================================= */
package org.apache.poi.poifs.crypt.dsig.facets;
-import java.security.GeneralSecurityException;
import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.crypto.MarshalException;
-import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Reference;
-import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLObject;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureException;
-import javax.xml.crypto.dsig.XMLSignatureFactory;
-import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import org.apache.poi.openxml4j.opc.PackageNamespaces;
-import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
-import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable;
-import org.apache.poi.util.POILogFactory;
-import org.apache.poi.util.POILogger;
+import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
+import org.apache.poi.util.Internal;
import org.w3c.dom.Document;
/**
* JSR105 Signature Facet base class.
*/
-public abstract class SignatureFacet implements SignatureConfigurable {
+@Internal
+public interface SignatureFacet {
- private static final POILogger LOG = POILogFactory.getLogger(SignatureFacet.class);
-
- public static final String XML_NS = XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
- public static final String XML_DIGSIG_NS = XMLSignature.XMLNS;
- public static final String OO_DIGSIG_NS = PackageNamespaces.DIGITAL_SIGNATURE;
- public static final String MS_DIGSIG_NS = "http://schemas.microsoft.com/office/2006/digsig";
- public static final String XADES_132_NS = "http://uri.etsi.org/01903/v1.3.2#";
- public static final String XADES_141_NS = "http://uri.etsi.org/01903/v1.4.1#";
-
- protected SignatureConfig signatureConfig;
-
- @Override
- public void setSignatureConfig(SignatureConfig signatureConfig) {
- this.signatureConfig = signatureConfig;
- }
+ String XML_NS = XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
+ String XML_DIGSIG_NS = XMLSignature.XMLNS;
+ String OO_DIGSIG_NS = PackageNamespaces.DIGITAL_SIGNATURE;
+ String MS_DIGSIG_NS = "http://schemas.microsoft.com/office/2006/digsig";
+ String XADES_132_NS = "http://uri.etsi.org/01903/v1.3.2#";
+ String XADES_141_NS = "http://uri.etsi.org/01903/v1.4.1#";
/**
* This method is being invoked by the XML signature service engine during
* pre-sign phase. Via this method a signature facet implementation can add
* signature facets to an XML signature.
- *
+ *
+ * @param signatureInfo the signature info object holding the OPCPackage and other document related data
* @param document the signature document to be used for imports
* @param references list of reference definitions
* @param objects objects to be signed/included in the signature document
* @throws XMLSignatureException
*/
- public void preSign(
- Document document
+ default void preSign(
+ SignatureInfo signatureInfo
+ , Document document
, List<Reference> references
, List<XMLObject> objects
) throws XMLSignatureException {
- // empty
+
}
/**
@@ -89,62 +76,12 @@ public abstract class SignatureFacet implements SignatureConfigurable {
* the post-sign phase. Via this method a signature facet can extend the XML
* signatures with for example key information.
*
+ * @param signatureInfo the signature info object holding the OPCPackage and other document related data
* @param document the signature document to be modified
* @throws MarshalException
*/
- public void postSign(Document document) throws MarshalException {
- // empty
- }
+ default void postSign(SignatureInfo signatureInfo, Document document) throws MarshalException {
- protected XMLSignatureFactory getSignatureFactory() {
- return signatureConfig.getSignatureFactory();
- }
-
- protected Transform newTransform(String canonicalizationMethod) throws XMLSignatureException {
- return newTransform(canonicalizationMethod, null);
- }
-
- protected Transform newTransform(String canonicalizationMethod, TransformParameterSpec paramSpec)
- throws XMLSignatureException {
- try {
- return getSignatureFactory().newTransform(canonicalizationMethod, paramSpec);
- } catch (GeneralSecurityException e) {
- throw new XMLSignatureException("unknown canonicalization method: "+canonicalizationMethod, e);
- }
- }
-
- protected Reference newReference(String uri, List<Transform> transforms, String type, String id, byte[] digestValue)
- throws XMLSignatureException {
- return newReference(uri, transforms, type, id, digestValue, signatureConfig);
}
- public static Reference newReference(
- String uri
- , List<Transform> transforms
- , String type
- , String id
- , byte[] digestValue
- , SignatureConfig signatureConfig)
- throws XMLSignatureException {
- // the references appear in the package signature or the package object
- // so we can use the default digest algorithm
- String digestMethodUri = signatureConfig.getDigestMethodUri();
- XMLSignatureFactory sigFac = signatureConfig.getSignatureFactory();
- DigestMethod digestMethod;
- try {
- digestMethod = sigFac.newDigestMethod(digestMethodUri, null);
- } catch (GeneralSecurityException e) {
- throw new XMLSignatureException("unknown digest method uri: "+digestMethodUri, e);
- }
-
- Reference reference;
- if (digestValue == null) {
- reference = sigFac.newReference(uri, digestMethod, transforms, type, id);
- } else {
- reference = sigFac.newReference(uri, digestMethod, transforms, type, id, digestValue);
- }
-
-
- return reference;
- }
} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/SignatureFacetHelper.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/SignatureFacetHelper.java
new file mode 100644
index 0000000000..e60771f563
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/SignatureFacetHelper.java
@@ -0,0 +1,75 @@
+/* ====================================================================
+ 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 org.apache.poi.poifs.crypt.dsig.facets;
+
+import java.security.GeneralSecurityException;
+import java.util.List;
+
+import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import javax.xml.crypto.dsig.spec.TransformParameterSpec;
+
+import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
+import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
+import org.apache.poi.util.Internal;
+
+@Internal
+final class SignatureFacetHelper {
+ private SignatureFacetHelper() {}
+
+ static Transform newTransform(SignatureInfo signatureInfo, String canonicalizationMethod) throws XMLSignatureException {
+ return newTransform(signatureInfo, canonicalizationMethod, null);
+ }
+
+ static Transform newTransform(SignatureInfo signatureInfo, String canonicalizationMethod, TransformParameterSpec paramSpec)
+ throws XMLSignatureException {
+ try {
+ return signatureInfo.getSignatureFactory().newTransform(canonicalizationMethod, paramSpec);
+ } catch (GeneralSecurityException e) {
+ throw new XMLSignatureException("unknown canonicalization method: "+canonicalizationMethod, e);
+ }
+ }
+
+ static Reference newReference(
+ SignatureInfo signatureInfo
+ , String uri
+ , List<Transform> transforms
+ , String type
+ , String id
+ , byte[] digestValue)
+ throws XMLSignatureException {
+ // the references appear in the package signature or the package object
+ // so we can use the default digest algorithm
+ SignatureConfig signatureConfig = signatureInfo.getSignatureConfig();
+ String digestMethodUri = signatureConfig.getDigestMethodUri();
+ XMLSignatureFactory sigFac = signatureInfo.getSignatureFactory();
+ DigestMethod digestMethod;
+ try {
+ digestMethod = sigFac.newDigestMethod(digestMethodUri, null);
+ } catch (GeneralSecurityException e) {
+ throw new XMLSignatureException("unknown digest method uri: "+digestMethodUri, e);
+ }
+
+ return (digestValue == null)
+ ? sigFac.newReference(uri, digestMethod, transforms, type, id)
+ : sigFac.newReference(uri, digestMethod, transforms, type, id, digestValue);
+ }
+}
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESSignatureFacet.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESSignatureFacet.java
index c8f04e8824..ce96f16a91 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESSignatureFacet.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESSignatureFacet.java
@@ -18,13 +18,15 @@
/* ====================================================================
This product contains an ASLv2 licensed version of the OOXML signer
package from the eID Applet project
- http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
Copyright (C) 2008-2014 FedICT.
- ================================================================= */
+ ================================================================= */
package org.apache.poi.poifs.crypt.dsig.facets;
import static java.util.Collections.singletonList;
+import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacetHelper.newReference;
+import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacetHelper.newTransform;
import java.security.MessageDigest;
import java.security.cert.CertificateEncodingException;
@@ -48,6 +50,7 @@ import javax.xml.crypto.dsig.XMLSignatureException;
import org.apache.poi.poifs.crypt.CryptoFunctions;
import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
+import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.apache.poi.poifs.crypt.dsig.services.SignaturePolicyService;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
@@ -77,36 +80,39 @@ import org.w3c.dom.Node;
* XAdES Signature Facet. Implements XAdES v1.4.1 which is compatible with XAdES
* v1.3.2. The implemented XAdES format is XAdES-BES/EPES. It's up to another
* part of the signature service to upgrade the XAdES-BES to a XAdES-X-L.
- *
+ *
* This implementation has been tested against an implementation that
* participated multiple ETSI XAdES plugtests.
- *
+ *
* @author Frank Cornelis
* @see <a href="http://en.wikipedia.org/wiki/XAdES">XAdES</a>
- *
+ *
*/
-public class XAdESSignatureFacet extends SignatureFacet {
+public class XAdESSignatureFacet implements SignatureFacet {
private static final POILogger LOG = POILogFactory.getLogger(XAdESSignatureFacet.class);
private static final String XADES_TYPE = "http://uri.etsi.org/01903#SignedProperties";
-
+
private final Map<String, String> dataObjectFormatMimeTypes = new HashMap<>();
@Override
public void preSign(
- Document document
+ SignatureInfo signatureInfo
+ , Document document
, List<Reference> references
, List<XMLObject> objects)
throws XMLSignatureException {
LOG.log(POILogger.DEBUG, "preSign");
+ SignatureConfig signatureConfig = signatureInfo.getSignatureConfig();
+
// QualifyingProperties
QualifyingPropertiesDocument qualDoc = QualifyingPropertiesDocument.Factory.newInstance();
QualifyingPropertiesType qualifyingProperties = qualDoc.addNewQualifyingProperties();
qualifyingProperties.setTarget("#" + signatureConfig.getPackageSignatureId());
-
+
// SignedProperties
SignedPropertiesType signedProperties = qualifyingProperties.addNewSignedProperties();
signedProperties.setId(signatureConfig.getXadesSignatureId());
@@ -115,35 +121,37 @@ public class XAdESSignatureFacet extends SignatureFacet {
SignedSignaturePropertiesType signedSignatureProperties = signedProperties.addNewSignedSignatureProperties();
// SigningTime
- addSigningTime(signedSignatureProperties);
+ addSigningTime(signatureInfo, signedSignatureProperties);
// SigningCertificate
- addCertificate(signedSignatureProperties);
+ addCertificate(signatureInfo, signedSignatureProperties);
// ClaimedRole
- addXadesRole(signedSignatureProperties);
+ addXadesRole(signatureInfo, signedSignatureProperties);
// XAdES-EPES
- addPolicy(signedSignatureProperties);
+ addPolicy(signatureInfo, signedSignatureProperties);
// DataObjectFormat
addMimeTypes(signedProperties);
// add XAdES ds:Object
- objects.add(addXadesObject(document, qualifyingProperties));
+ objects.add(addXadesObject(signatureInfo, document, qualifyingProperties));
// add XAdES ds:Reference
- references.add(addXadesReference());
+ references.add(addXadesReference(signatureInfo));
}
- private void addSigningTime(SignedSignaturePropertiesType signedSignatureProperties) {
+ private void addSigningTime(SignatureInfo signatureInfo, SignedSignaturePropertiesType signedSignatureProperties) {
+ SignatureConfig signatureConfig = signatureInfo.getSignatureConfig();
Calendar xmlGregorianCalendar = Calendar.getInstance(TimeZone.getTimeZone("Z"), Locale.ROOT);
xmlGregorianCalendar.setTime(signatureConfig.getExecutionTime());
xmlGregorianCalendar.clear(Calendar.MILLISECOND);
signedSignatureProperties.setSigningTime(xmlGregorianCalendar);
}
- private void addCertificate(SignedSignaturePropertiesType signedSignatureProperties) {
+ private void addCertificate(SignatureInfo signatureInfo, SignedSignaturePropertiesType signedSignatureProperties) {
+ SignatureConfig signatureConfig = signatureInfo.getSignatureConfig();
List<X509Certificate> chain = signatureConfig.getSigningCertificateChain();
if (chain == null || chain.isEmpty()) {
throw new RuntimeException("no signing certificate chain available");
@@ -153,7 +161,8 @@ public class XAdESSignatureFacet extends SignatureFacet {
setCertID(certId, signatureConfig, signatureConfig.isXadesIssuerNameNoReverseOrder(), chain.get(0));
}
- private void addXadesRole(SignedSignaturePropertiesType signedSignatureProperties) {
+ private void addXadesRole(SignatureInfo signatureInfo, SignedSignaturePropertiesType signedSignatureProperties) {
+ SignatureConfig signatureConfig = signatureInfo.getSignatureConfig();
String role = signatureConfig.getXadesRole();
if (role == null || role.isEmpty()) {
return;
@@ -168,7 +177,8 @@ public class XAdESSignatureFacet extends SignatureFacet {
insertXChild(claimedRole, roleString);
}
- private void addPolicy(SignedSignaturePropertiesType signedSignatureProperties) {
+ private void addPolicy(SignatureInfo signatureInfo, SignedSignaturePropertiesType signedSignatureProperties) {
+ SignatureConfig signatureConfig = signatureInfo.getSignatureConfig();
SignaturePolicyService policyService = signatureConfig.getSignaturePolicyService();
if (policyService == null) {
if (signatureConfig.isXadesSignaturePolicyImplied()) {
@@ -221,22 +231,23 @@ public class XAdESSignatureFacet extends SignatureFacet {
});
}
- private XMLObject addXadesObject(Document document, QualifyingPropertiesType qualifyingProperties) {
+ private XMLObject addXadesObject(SignatureInfo signatureInfo, Document document, QualifyingPropertiesType qualifyingProperties) {
Node qualDocElSrc = qualifyingProperties.getDomNode();
Node qualDocEl = document.importNode(qualDocElSrc, true);
List<XMLStructure> xadesObjectContent = Arrays.asList(new DOMStructure(qualDocEl));
- return getSignatureFactory().newXMLObject(xadesObjectContent, null, null, null);
+ return signatureInfo.getSignatureFactory().newXMLObject(xadesObjectContent, null, null, null);
}
- private Reference addXadesReference() throws XMLSignatureException {
- List<Transform> transforms = singletonList(newTransform(CanonicalizationMethod.INCLUSIVE));
- return newReference("#"+signatureConfig.getXadesSignatureId(), transforms, XADES_TYPE, null, null);
+ private Reference addXadesReference(SignatureInfo signatureInfo) throws XMLSignatureException {
+ SignatureConfig signatureConfig = signatureInfo.getSignatureConfig();
+ List<Transform> transforms = singletonList(newTransform(signatureInfo, CanonicalizationMethod.INCLUSIVE));
+ return newReference(signatureInfo, "#"+signatureConfig.getXadesSignatureId(), transforms, XADES_TYPE, null, null);
}
/**
* Gives back the JAXB DigestAlgAndValue data structure.
*
- * @param digestAlgAndValue the parent for the new digest element
+ * @param digestAlgAndValue the parent for the new digest element
* @param data the data to be digested
* @param digestAlgo the digest algorithm
*/
@@ -246,7 +257,7 @@ public class XAdESSignatureFacet extends SignatureFacet {
HashAlgorithm digestAlgo) {
DigestMethodType digestMethod = digestAlgAndValue.addNewDigestMethod();
digestMethod.setAlgorithm(SignatureConfig.getDigestMethodUri(digestAlgo));
-
+
MessageDigest messageDigest = CryptoFunctions.getMessageDigest(digestAlgo);
byte[] digestValue = messageDigest.digest(data);
digestAlgAndValue.setDigestValue(digestValue);
@@ -264,7 +275,7 @@ public class XAdESSignatureFacet extends SignatureFacet {
* Make sure the DN is encoded using the same order as present
* within the certificate. This is an Office2010 work-around.
* Should be reverted back.
- *
+ *
* XXX: not correct according to RFC 4514.
*/
// TODO: check if issuerName is different on getTBSCertificate
@@ -283,14 +294,14 @@ public class XAdESSignatureFacet extends SignatureFacet {
throw new RuntimeException("certificate encoding error: "
+ e.getMessage(), e);
}
- DigestAlgAndValueType certDigest = certId.addNewCertDigest();
+ DigestAlgAndValueType certDigest = certId.addNewCertDigest();
setDigestAlgAndValue(certDigest, encodedCertificate, signatureConfig.getXadesDigestAlgo());
}
/**
* Adds a mime-type for the given ds:Reference (referred via its @URI). This
* information is added via the xades:DataObjectFormat element.
- *
+ *
* @param dsReferenceUri
* @param mimetype
*/
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESXLSignatureFacet.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESXLSignatureFacet.java
index e00de87b7c..60b9e26e67 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESXLSignatureFacet.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESXLSignatureFacet.java
@@ -18,9 +18,9 @@
/* ====================================================================
This product contains an ASLv2 licensed version of the OOXML signer
package from the eID Applet project
- http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
Copyright (C) 2008-2014 FedICT.
- ================================================================= */
+ ================================================================= */
package org.apache.poi.poifs.crypt.dsig.facets;
@@ -47,6 +47,8 @@ import java.util.UUID;
import javax.xml.crypto.MarshalException;
+import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
+import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.apache.poi.poifs.crypt.dsig.services.RevocationData;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.POILogFactory;
@@ -73,18 +75,18 @@ import org.w3c.dom.NodeList;
/**
* XAdES-X-L v1.4.1 signature facet. This signature facet implementation will
* upgrade a given XAdES-BES/EPES signature to XAdES-X-L.
- *
+ *
* We don't inherit from XAdESSignatureFacet as we also want to be able to use
* this facet out of the context of a signature creation. This signature facet
* assumes that the signature is already XAdES-BES/EPES compliant.
- *
+ *
* This implementation has been tested against an implementation that
* participated multiple ETSI XAdES plugtests.
- *
+ *
* @author Frank Cornelis
* @see XAdESSignatureFacet
*/
-public class XAdESXLSignatureFacet extends SignatureFacet {
+public class XAdESXLSignatureFacet implements SignatureFacet {
private static final POILogger LOG = POILogFactory.getLogger(XAdESXLSignatureFacet.class);
@@ -99,9 +101,11 @@ public class XAdESXLSignatureFacet extends SignatureFacet {
}
@Override
- public void postSign(Document document) throws MarshalException {
+ public void postSign(SignatureInfo signatureInfo, Document document) throws MarshalException {
LOG.log(POILogger.DEBUG, "XAdES-X-L post sign phase");
+ SignatureConfig signatureConfig = signatureInfo.getSignatureConfig();
+
QualifyingPropertiesDocument qualDoc = null;
QualifyingPropertiesType qualProps = null;
@@ -127,18 +131,18 @@ public class XAdESXLSignatureFacet extends SignatureFacet {
if (unsignedSigProps == null) {
unsignedSigProps = unsignedProps.addNewUnsignedSignatureProperties();
}
-
+
// create the XAdES-T time-stamp
NodeList nlSigVal = document.getElementsByTagNameNS(XML_DIGSIG_NS, "SignatureValue");
if (nlSigVal.getLength() != 1) {
throw new IllegalArgumentException("SignatureValue is not set.");
}
-
+
RevocationData tsaRevocationDataXadesT = new RevocationData();
LOG.log(POILogger.DEBUG, "creating XAdES-T time-stamp");
XAdESTimeStampType signatureTimeStamp = createXAdESTimeStamp
- (Collections.singletonList(nlSigVal.item(0)), tsaRevocationDataXadesT);
+ (signatureInfo, Collections.singletonList(nlSigVal.item(0)), tsaRevocationDataXadesT);
// marshal the XAdES-T extension
unsignedSigProps.addNewSignatureTimeStamp().set(signatureTimeStamp);
@@ -158,7 +162,7 @@ public class XAdESXLSignatureFacet extends SignatureFacet {
}
// XAdES-C: complete certificate refs
- CompleteCertificateRefsType completeCertificateRefs =
+ CompleteCertificateRefsType completeCertificateRefs =
unsignedSigProps.addNewCompleteCertificateRefs();
CertIDListType certIdList = completeCertificateRefs.addNewCertRefs();
@@ -176,7 +180,7 @@ public class XAdESXLSignatureFacet extends SignatureFacet {
}
// XAdES-C: complete revocation refs
- CompleteRevocationRefsType completeRevocationRefs =
+ CompleteRevocationRefsType completeRevocationRefs =
unsignedSigProps.addNewCompleteRevocationRefs();
RevocationData revocationData = signatureConfig.getRevocationDataService()
.getRevocationData(certChain);
@@ -212,22 +216,22 @@ public class XAdESXLSignatureFacet extends SignatureFacet {
for (byte[] ocsp : revocationData.getOCSPs()) {
try {
OCSPRefType ocspRef = ocspRefs.addNewOCSPRef();
-
+
DigestAlgAndValueType digestAlgAndValue = ocspRef.addNewDigestAlgAndValue();
XAdESSignatureFacet.setDigestAlgAndValue(digestAlgAndValue, ocsp, signatureConfig.getDigestAlgo());
-
+
OCSPIdentifierType ocspIdentifier = ocspRef.addNewOCSPIdentifier();
-
+
OCSPResp ocspResp = new OCSPResp(ocsp);
-
+
BasicOCSPResp basicOcspResp = (BasicOCSPResp)ocspResp.getResponseObject();
-
+
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Z"), Locale.ROOT);
cal.setTime(basicOcspResp.getProducedAt());
ocspIdentifier.setProducedAt(cal);
-
+
ResponderIDType responderId = ocspIdentifier.addNewResponderID();
-
+
RespID respId = basicOcspResp.getResponderId();
ResponderID ocspResponderId = respId.toASN1Primitive();
DERTaggedObject derTaggedObject = (DERTaggedObject)ocspResponderId.toASN1Primitive();
@@ -247,7 +251,7 @@ public class XAdESXLSignatureFacet extends SignatureFacet {
}
// marshal XAdES-C
-
+
// XAdES-X Type 1 timestamp
List<Node> timeStampNodesXadesX1 = new ArrayList<>();
timeStampNodesXadesX1.add(nlSigVal.item(0));
@@ -258,7 +262,7 @@ public class XAdESXLSignatureFacet extends SignatureFacet {
RevocationData tsaRevocationDataXadesX1 = new RevocationData();
LOG.log(POILogger.DEBUG, "creating XAdES-X time-stamp");
XAdESTimeStampType timeStampXadesX1 = createXAdESTimeStamp
- (timeStampNodesXadesX1, tsaRevocationDataXadesX1);
+ (signatureInfo, timeStampNodesXadesX1, tsaRevocationDataXadesX1);
if (tsaRevocationDataXadesX1.hasRevocationDataEntries()) {
ValidationDataType timeStampXadesX1ValidationData = createValidationData(tsaRevocationDataXadesX1);
insertXChild(unsignedSigProps, timeStampXadesX1ValidationData);
@@ -277,7 +281,7 @@ public class XAdESXLSignatureFacet extends SignatureFacet {
throw new RuntimeException("certificate encoding error: " + e.getMessage(), e);
}
}
-
+
RevocationValuesType revocationValues = unsignedSigProps.addNewRevocationValues();
createRevocationValues(revocationValues, revocationData);
@@ -330,18 +334,21 @@ public class XAdESXLSignatureFacet extends SignatureFacet {
}
private XAdESTimeStampType createXAdESTimeStamp(
+ SignatureInfo signatureInfo,
List<Node> nodeList,
RevocationData revocationData) {
+ SignatureConfig signatureConfig = signatureInfo.getSignatureConfig();
byte[] c14nSignatureValueElement = getC14nValue(nodeList, signatureConfig.getXadesCanonicalizationMethod());
- return createXAdESTimeStamp(c14nSignatureValueElement, revocationData);
+ return createXAdESTimeStamp(signatureInfo, c14nSignatureValueElement, revocationData);
}
- private XAdESTimeStampType createXAdESTimeStamp(byte[] data, RevocationData revocationData) {
+ private XAdESTimeStampType createXAdESTimeStamp(SignatureInfo signatureInfo, byte[] data, RevocationData revocationData) {
+ SignatureConfig signatureConfig = signatureInfo.getSignatureConfig();
// create the time-stamp
byte[] timeStampToken;
try {
- timeStampToken = signatureConfig.getTspService().timeStamp(data, revocationData);
+ timeStampToken = signatureConfig.getTspService().timeStamp(signatureInfo, data, revocationData);
} catch (Exception e) {
throw new RuntimeException("error while creating a time-stamp: "
+ e.getMessage(), e);
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java
index c7fd85c468..925f463077 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java
@@ -18,9 +18,9 @@
/* ====================================================================
This product contains an ASLv2 licensed version of the OOXML signer
package from the eID Applet project
- http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
Copyright (C) 2008-2014 FedICT.
- ================================================================= */
+ ================================================================= */
package org.apache.poi.poifs.crypt.dsig.services;
@@ -47,6 +47,7 @@ import java.util.Map;
import org.apache.poi.poifs.crypt.CryptoFunctions;
import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
+import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.POILogFactory;
@@ -72,16 +73,14 @@ import org.bouncycastle.tsp.TimeStampToken;
/**
* A TSP time-stamp service implementation.
- *
+ *
* @author Frank Cornelis
- *
+ *
*/
public class TSPTimeStampService implements TimeStampService {
private static final POILogger LOG = POILogFactory.getLogger(TSPTimeStampService.class);
- private SignatureConfig signatureConfig;
-
/**
* Maps the digest algorithm to corresponding OID value.
*/
@@ -97,8 +96,9 @@ public class TSPTimeStampService implements TimeStampService {
}
@SuppressWarnings({"unchecked","squid:S2647"})
- public byte[] timeStamp(byte[] data, RevocationData revocationData)
- throws Exception {
+ public byte[] timeStamp(SignatureInfo signatureInfo, byte[] data, RevocationData revocationData) throws Exception {
+ SignatureConfig signatureConfig = signatureInfo.getSignatureConfig();
+
// digest the message
MessageDigest messageDigest = CryptoFunctions.getMessageDigest(signatureConfig.getTspDigestAlgo());
byte[] digest = messageDigest.digest(data);
@@ -170,7 +170,7 @@ public class TSPTimeStampService implements TimeStampService {
huc.disconnect();
}
- if (!contentType.startsWith(signatureConfig.isTspOldProtocol()
+ if (!contentType.startsWith(signatureConfig.isTspOldProtocol()
? "application/timestamp-response"
: "application/timestamp-reply"
)) {
@@ -178,7 +178,7 @@ public class TSPTimeStampService implements TimeStampService {
// dump the first few bytes
": " + HexDump.dump(bos.toByteArray(), 0, 0, 200));
}
-
+
if (bos.size() == 0) {
throw new RuntimeException("Content-Length is zero");
}
@@ -209,7 +209,7 @@ public class TSPTimeStampService implements TimeStampService {
// TSP signer certificates retrieval
Collection<X509CertificateHolder> certificates = timeStampToken.getCertificates().getMatches(null);
-
+
X509CertificateHolder signerCert = null;
Map<X500Name, X509CertificateHolder> certificateMap = new HashMap<>();
for (X509CertificateHolder certificate : certificates) {
@@ -245,7 +245,7 @@ public class TSPTimeStampService implements TimeStampService {
BcDigestCalculatorProvider calculator = new BcDigestCalculatorProvider();
BcRSASignerInfoVerifierBuilder verifierBuilder = new BcRSASignerInfoVerifierBuilder(nameGen, sigAlgoFinder, hashAlgoFinder, calculator);
SignerInformationVerifier verifier = verifierBuilder.build(holder);
-
+
timeStampToken.validate(verifier);
// verify TSP signer certificate
@@ -258,8 +258,4 @@ public class TSPTimeStampService implements TimeStampService {
return timeStampToken.getEncoded();
}
-
- public void setSignatureConfig(SignatureConfig signatureConfig) {
- this.signatureConfig = signatureConfig;
- }
} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampService.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampService.java
index ede39ac357..72561af9bd 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampService.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampService.java
@@ -18,28 +18,26 @@
/* ====================================================================
This product contains an ASLv2 licensed version of the OOXML signer
package from the eID Applet project
- http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
Copyright (C) 2008-2014 FedICT.
- ================================================================= */
+ ================================================================= */
package org.apache.poi.poifs.crypt.dsig.services;
-import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable;
-
+import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
/**
* Interface for a time-stamp service.
- *
+ *
* @author Frank Cornelis
- *
*/
-public interface TimeStampService extends SignatureConfigurable {
+public interface TimeStampService {
/**
* Gives back the encoded time-stamp token for the given array of data
* bytes. We assume that the time-stamp token itself contains its full
* certificate chain required for proper validation.
- *
+ *
* @param data
* the data to be time-stamped.
* @param revocationData
@@ -49,6 +47,5 @@ public interface TimeStampService extends SignatureConfigurable {
* @throws Exception
* in case something went wrong.
*/
- byte[] timeStamp(byte[] data, RevocationData revocationData)
- throws Exception;
+ byte[] timeStamp(SignatureInfo signatureInfo, byte[] data, RevocationData revocationData) throws Exception;
}
diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java
index e621f51e0d..1d9e154542 100644
--- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java
+++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java
@@ -104,27 +104,18 @@ import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.xmlbeans.SystemProperties;
import org.apache.xmlbeans.XmlObject;
-import org.bouncycastle.asn1.DERIA5String;
import org.bouncycastle.asn1.DEROctetString;
-import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.CRLNumber;
-import org.bouncycastle.asn1.x509.CRLReason;
-import org.bouncycastle.asn1.x509.DistributionPoint;
-import org.bouncycastle.asn1.x509.DistributionPointName;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.Extensions;
-import org.bouncycastle.asn1.x509.GeneralName;
-import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import org.bouncycastle.cert.X509CRLHolder;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509ExtensionUtils;
@@ -141,7 +132,6 @@ import org.bouncycastle.cert.ocsp.OCSPReqBuilder;
import org.bouncycastle.cert.ocsp.OCSPResp;
import org.bouncycastle.cert.ocsp.OCSPRespBuilder;
import org.bouncycastle.cert.ocsp.Req;
-import org.bouncycastle.cert.ocsp.RevokedStatus;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory;
import org.bouncycastle.openssl.PEMParser;
@@ -196,7 +186,7 @@ public class TestSignatureInfo {
String additionalJar = System.getProperty("additionaljar");
//System.out.println("Having: " + additionalJar);
Assume.assumeTrue("Not running TestSignatureInfo because we are testing with additionaljar set to " + additionalJar,
- additionalJar == null || additionalJar.trim().length() == 0);
+ additionalJar == null || additionalJar.trim().length() == 0);
System.setProperty("org.apache.xml.security.ignoreLineBreaks", "true");
@@ -207,98 +197,97 @@ public class TestSignatureInfo {
@Ignore("This test is very sensitive, it breaks with every little change to the produced XML")
@Test
public void bug61182() throws Exception {
- String pfxInput =
- "H4sIAAAAAAAAAFXTfzzTeRwH8P2uGRmG6hKSmJh9a2HsuPy60VnHCEU6v86sieZH2Jr2qFl+s+ZHJ5tfUcfKb4uho/OjiFq1qTv5ceFyp0PqEK"+
- "fH4+66++Pz+Dwer9fj8f7r9cRzEd4QMBTPRWxDIM14ZN47NfAWsJgL34Bx4at4Lvwdngvd9b8KqgbjQpGbMXzzgRGovytVFTBEzIXU47kQCd4U"+
- "ofJPvHl8JwyTjRS55hbKoor3UJLDE1i/PcPKCBAIDATjQlKiK67XjVYdcnkZgD2txroiAUb8W9dtn57DvTsbM+3wIsdocXDEN7TdPKgaSl+tU1"+
- "xq9oqiB5yMaZCPho8uUEbFU9U6u3N7lEMLTJGeA0RfX+5FMRrpXPFrbrlJ8uNUCE2H247P28Ckyfqlsy32yeKg/HTbH5JpqUDNw2B32+SaiRw7"+
- "ofRMePUpaAoK7KYgmd5ZIc0rLLYjJBfOWCb28xlrGhbpJvdToFdqt5PXVjEz5YOJ6g7W0fskuKW9/iZP0yLEVpR9XkkHmb6tfpcE8YwCdWNCan"+
- "LvAsco25JdF1j2/FLAMVU79HdOex07main90dy40511OZtTGZ+TdVd3lKZ7D3clEg9hLESHwSNnZ6239X4yLM4xYSElQ/hqSbwdmiozYG9PhF2"+
- "Zf0XaZnxzTK0Iot+rJ3kYoxWTLE8DR9leV62Ywbtlg4mapYOxb3lT7fQ1x4EQ44flh2oFWSPLR8LMbsc6jzJsV6OZ3TrODjHEdw9W+8OD32vd8"+
- "XQ6iCaIHcrSOn6qS0TKLr786234eeSAhvAQbEsVn7vrvc/487Be/O2e/+5Y5zRq2zAtz6pfcNyraJNDqMW1inNkgJ3t3VESbZ3pNzyl3KHILs0"+
- "51dY6msDYSlWhw40TglXxj9rw95O6gFWIuN012W/vhS50jpKXcao4gc1aLaXtJXxirbRkpZ/0e7a0pD6TDa7+GxEdEEML3VGo9udD5YUKhU3y7"+
- "SzWAgN6WIEIglq7LilvCjqIVLIfg8CvVGL9f5iSsCDf5hef4vMxbyvcjINuy06gZu+iPYOWNxjfrwKGYzoqqotK2aywgYVrPMh0JovfkDuN95n"+
- "MdVlYHbN1Mnn4TxAwuv+u3AkBlDZvRUUCwoDMUGxeMNPhTaAgWl60xhhBgCBaEMgAACReMAav7n3x598IDYJ9GxGXRAwaPOT/kfO/1AgPqLQkp"+
- "MiIVaHthnUS4v2y32e2BjdMPyIImUTBW3cV3R5tjVQm0MOm+D2C5+bBW9vHLjLR4lun4toQiY3Ls/v4bES/OJ4EmpZk5xhL9i5ClofYZNEsxFn"+
- "An/q821Tg+Cq9Er4XYGQe8ogjjLJ2b7dUsJ3auFQFNUJF7Ke7yUL2EeYYxl6vz5l4q5u8704mRbFts1E1eWMp6WIy91GPrsVlRGvtuNERfrjfE"+
- "YtzUI3Flcv65zJUbUBEzUnTS0fEYso2XyToAl8kb251mUY2o2lJzv5dp/1htmcjeeP2MjxC+3S45ljx7jd52Pv9XAat+ryiauFOF7YgztkoWWD"+
- "h62tplPH1bzDV+d0NLdaE5AfVJ09HuUYTFS+iggtvT5Euyk+unj4N2XvzW91n+GNjtgWfKOHmkinUPvYRh70Jv+wlPJrVaT8mL7GxJLqDC9jbv"+
- "Gznoiae6es+wQejnk3XjU366MrK/zXxngBYj9J6NnXc9mMiTFLX8WqQ8iTelTAFs2NJzPoDzrBUz4JFIEOa6Dja6dULc68g1jFDTeEHZyra7RZ"+
- "2ElqGDEqcNRo3SNX6feMy9EF1GOyZK0Sa87KwjKw8aM68dpsIYjfLcTXaZ6atg0BKfMnl6axeUGEaIFSP7rzj9wjzumRbG3jgUVp2lX5AK/tsO"+
- "7R4TQX/9/H6RiN34c9KldmPZZGANXzzTajZS9mR2OSvlJ+F4AgSko4htrMAKFTBu51/5SWNsO1vlRaaG48ZRJ+8PzuHQMdvS36gNpRPi7jhF1S"+
- "H3B2ycI4y0VURv6SrqJNUY/X645ZFJQ+eBO+ptG7o8axf1dcqh2beiQk+GRTeZ37LVeUlaeo9vl1/+8tyBfyT2v5lFC5E19WdKIyCuZe7r99Px"+
- "D/Od4Qj0TA92+DQnbCQTCMy/wwse9O4gsEebkkpPIP5GBV3Q0YBsj75XE0uSFQ1tCZSW8bNa9MUJZ/nPBfExohHlgGAAA=";
+ final String pfxInput =
+ "H4sIAAAAAAAAAFXTfzzTeRwH8P2uGRmG6hKSmJh9a2HsuPy60VnHCEU6v86sieZH2Jr2qFl+s+ZHJ5tfUcfKb4uho/OjiFq1qTv5ceFyp0PqEK"+
+ "fH4+66++Pz+Dwer9fj8f7r9cRzEd4QMBTPRWxDIM14ZN47NfAWsJgL34Bx4at4Lvwdngvd9b8KqgbjQpGbMXzzgRGovytVFTBEzIXU47kQCd4U"+
+ "ofJPvHl8JwyTjRS55hbKoor3UJLDE1i/PcPKCBAIDATjQlKiK67XjVYdcnkZgD2txroiAUb8W9dtn57DvTsbM+3wIsdocXDEN7TdPKgaSl+tU1"+
+ "xq9oqiB5yMaZCPho8uUEbFU9U6u3N7lEMLTJGeA0RfX+5FMRrpXPFrbrlJ8uNUCE2H247P28Ckyfqlsy32yeKg/HTbH5JpqUDNw2B32+SaiRw7"+
+ "ofRMePUpaAoK7KYgmd5ZIc0rLLYjJBfOWCb28xlrGhbpJvdToFdqt5PXVjEz5YOJ6g7W0fskuKW9/iZP0yLEVpR9XkkHmb6tfpcE8YwCdWNCan"+
+ "LvAsco25JdF1j2/FLAMVU79HdOex07main90dy40511OZtTGZ+TdVd3lKZ7D3clEg9hLESHwSNnZ6239X4yLM4xYSElQ/hqSbwdmiozYG9PhF2"+
+ "Zf0XaZnxzTK0Iot+rJ3kYoxWTLE8DR9leV62Ywbtlg4mapYOxb3lT7fQ1x4EQ44flh2oFWSPLR8LMbsc6jzJsV6OZ3TrODjHEdw9W+8OD32vd8"+
+ "XQ6iCaIHcrSOn6qS0TKLr786234eeSAhvAQbEsVn7vrvc/487Be/O2e/+5Y5zRq2zAtz6pfcNyraJNDqMW1inNkgJ3t3VESbZ3pNzyl3KHILs0"+
+ "51dY6msDYSlWhw40TglXxj9rw95O6gFWIuN012W/vhS50jpKXcao4gc1aLaXtJXxirbRkpZ/0e7a0pD6TDa7+GxEdEEML3VGo9udD5YUKhU3y7"+
+ "SzWAgN6WIEIglq7LilvCjqIVLIfg8CvVGL9f5iSsCDf5hef4vMxbyvcjINuy06gZu+iPYOWNxjfrwKGYzoqqotK2aywgYVrPMh0JovfkDuN95n"+
+ "MdVlYHbN1Mnn4TxAwuv+u3AkBlDZvRUUCwoDMUGxeMNPhTaAgWl60xhhBgCBaEMgAACReMAav7n3x598IDYJ9GxGXRAwaPOT/kfO/1AgPqLQkp"+
+ "MiIVaHthnUS4v2y32e2BjdMPyIImUTBW3cV3R5tjVQm0MOm+D2C5+bBW9vHLjLR4lun4toQiY3Ls/v4bES/OJ4EmpZk5xhL9i5ClofYZNEsxFn"+
+ "An/q821Tg+Cq9Er4XYGQe8ogjjLJ2b7dUsJ3auFQFNUJF7Ke7yUL2EeYYxl6vz5l4q5u8704mRbFts1E1eWMp6WIy91GPrsVlRGvtuNERfrjfE"+
+ "YtzUI3Flcv65zJUbUBEzUnTS0fEYso2XyToAl8kb251mUY2o2lJzv5dp/1htmcjeeP2MjxC+3S45ljx7jd52Pv9XAat+ryiauFOF7YgztkoWWD"+
+ "h62tplPH1bzDV+d0NLdaE5AfVJ09HuUYTFS+iggtvT5Euyk+unj4N2XvzW91n+GNjtgWfKOHmkinUPvYRh70Jv+wlPJrVaT8mL7GxJLqDC9jbv"+
+ "Gznoiae6es+wQejnk3XjU366MrK/zXxngBYj9J6NnXc9mMiTFLX8WqQ8iTelTAFs2NJzPoDzrBUz4JFIEOa6Dja6dULc68g1jFDTeEHZyra7RZ"+
+ "2ElqGDEqcNRo3SNX6feMy9EF1GOyZK0Sa87KwjKw8aM68dpsIYjfLcTXaZ6atg0BKfMnl6axeUGEaIFSP7rzj9wjzumRbG3jgUVp2lX5AK/tsO"+
+ "7R4TQX/9/H6RiN34c9KldmPZZGANXzzTajZS9mR2OSvlJ+F4AgSko4htrMAKFTBu51/5SWNsO1vlRaaG48ZRJ+8PzuHQMdvS36gNpRPi7jhF1S"+
+ "H3B2ycI4y0VURv6SrqJNUY/X645ZFJQ+eBO+ptG7o8axf1dcqh2beiQk+GRTeZ37LVeUlaeo9vl1/+8tyBfyT2v5lFC5E19WdKIyCuZe7r99Px"+
+ "D/Od4Qj0TA92+DQnbCQTCMy/wwse9O4gsEebkkpPIP5GBV3Q0YBsj75XE0uSFQ1tCZSW8bNa9MUJZ/nPBfExohHlgGAAA=";
+
+ // Unix
+ final String unixSignExp =
+ "QkqTFQZjXagjRAoOWKpAGa8AR0rKqkSfBtfSWqtjBmTgyjarn+t2POHkpySIpheHAbg+90GKSH88ACMtPHbG7q" +
+ "FL4gtgAD9Kjew6j16j0IRBwy145UlPrSLFMfF7YF7UlU1k1LBkIlRJ6Fv4MAJl6XspuzZOZIUmHZrWrdxycUQ=";
+
+ // Windows
+ final String winSignExp =
+ "GmAlL7+bT1r3FsMHJOp3pKg8betblYieZTjhMIrPZPRBbSzjO7KsYRGNtr0aOE3qr8xzyYJN6/8QdF5X7pUEUc" +
+ "2m8ctrm7s5o2vZTkAqk9ENJGDjBPXX7TnuVOiVeL1cJdtjHC2QpjtRwkFR+B54G6b1OXLOFuQpP3vqR3+/XXE=";
+
+ // Mac
+ final String macSignExp =
+ "NZedY/LNTYU4nAUEUhIOg5+fKdgVtzRXKmdD3v+47E7Mb84oeiUGv9cCEE91DU3StF/JFIhjOJqavOzKnCsNcz" +
+ "NJ4j/inggUl1OJUsicqIGQnA7E8vzWnN1kf5lINgJLv+0PyrrX9sQZbItzxUpgqyOFYcD0trid+31nRt4wtaA=";
+
+
Calendar cal = LocaleUtil.getLocaleCalendar(LocaleUtil.TIMEZONE_UTC);
cal.clear();
cal.setTimeZone(LocaleUtil.TIMEZONE_UTC);
cal.set(2017, Calendar.JULY, 1);
- SignatureConfig signatureConfig = prepareConfig("test", "CN=Test", pfxInput);
+ SignatureConfig signatureConfig = prepareConfig(pfxInput);
signatureConfig.setExecutionTime(cal.getTime());
SignatureInfo si = new SignatureInfo();
si.setSignatureConfig(signatureConfig);
- XSSFWorkbook wb1 = new XSSFWorkbook();
- wb1.createSheet().createRow(1).createCell(1).setCellValue("Test");
ByteArrayOutputStream bos = new ByteArrayOutputStream(100000);
- wb1.write(bos);
- wb1.close();
-
- OPCPackage pkg1 = OPCPackage.open(new ByteArrayInputStream(bos.toByteArray()));
+ try (XSSFWorkbook wb1 = new XSSFWorkbook()) {
+ wb1.createSheet().createRow(1).createCell(1).setCellValue("Test");
+ wb1.write(bos);
+ }
- signatureConfig.setOpcPackage(pkg1);
- si.confirmSignature();
- assertTrue(si.verifySignature());
- bos.reset();
- pkg1.save(bos);
- pkg1.close();
-
- XSSFWorkbook wb2 = new XSSFWorkbook(new ByteArrayInputStream(bos.toByteArray()));
- assertEquals("Test", wb2.getSheetAt(0).getRow(1).getCell(1).getStringCellValue());
- OPCPackage pkg2 = wb2.getPackage();
- signatureConfig.setOpcPackage(pkg2);
- assertTrue(si.verifySignature());
-
- // xmlbeans adds line-breaks depending on the system setting, so we get different
- // test results on Unix/Mac/Windows
- // if the xml documents eventually change, this test needs to be run with the
- // separator set to the various system configurations
- String sep = SystemProperties.getProperty( "line.separator" );
- String signExp;
- assumeTrue("Hashes only known for Windows/Unix/Mac", sep == null || "\n".equals(sep) || "\r\n".equals(sep) || "\r".equals(sep));
- if (sep == null || "\n".equals(sep)) {
- // Unix
- signExp =
- "QkqTFQZjXagjRAoOWKpAGa8AR0rKqkSfBtfSWqtjBmTgyjarn+t2POHkpySIpheHAbg+90GKSH88ACMtPHbG7q"+
- "FL4gtgAD9Kjew6j16j0IRBwy145UlPrSLFMfF7YF7UlU1k1LBkIlRJ6Fv4MAJl6XspuzZOZIUmHZrWrdxycUQ=";
- } else if ("\r\n".equals(sep)){
- // Windows
- signExp =
- "GmAlL7+bT1r3FsMHJOp3pKg8betblYieZTjhMIrPZPRBbSzjO7KsYRGNtr0aOE3qr8xzyYJN6/8QdF5X7pUEUc"+
- "2m8ctrm7s5o2vZTkAqk9ENJGDjBPXX7TnuVOiVeL1cJdtjHC2QpjtRwkFR+B54G6b1OXLOFuQpP3vqR3+/XXE=";
- } else {
- // Mac
- signExp =
- "NZedY/LNTYU4nAUEUhIOg5+fKdgVtzRXKmdD3v+47E7Mb84oeiUGv9cCEE91DU3StF/JFIhjOJqavOzKnCsNcz"+
- "NJ4j/inggUl1OJUsicqIGQnA7E8vzWnN1kf5lINgJLv+0PyrrX9sQZbItzxUpgqyOFYcD0trid+31nRt4wtaA=";
+ try (OPCPackage pkg1 = OPCPackage.open(new ByteArrayInputStream(bos.toByteArray()))) {
+ si.setOpcPackage(pkg1);
+ si.confirmSignature();
+ assertTrue(si.verifySignature());
+ bos.reset();
+ pkg1.save(bos);
}
- String signAct = si.getSignatureParts().iterator().next().
- getSignatureDocument().getSignature().getSignatureValue().getStringValue();
- assertEquals(signExp, signAct);
+ try (XSSFWorkbook wb2 = new XSSFWorkbook(new ByteArrayInputStream(bos.toByteArray()))) {
+ assertEquals("Test", wb2.getSheetAt(0).getRow(1).getCell(1).getStringCellValue());
+ OPCPackage pkg2 = wb2.getPackage();
+ si.setOpcPackage(pkg2);
+ assertTrue(si.verifySignature());
- pkg2.close();
- wb2.close();
+ // xmlbeans adds line-breaks depending on the system setting, so we get different
+ // test results on Unix/Mac/Windows
+ // if the xml documents eventually change, this test needs to be run with the
+ // separator set to the various system configurations
+ String sep = SystemProperties.getProperty("line.separator");
+ String signExp;
+ assumeTrue("Hashes only known for Windows/Unix/Mac", sep == null || "\n".equals(sep) || "\r\n".equals(sep) || "\r".equals(sep));
+ signExp = (sep == null || "\n".equals(sep)) ? unixSignExp : ("\r\n".equals(sep)) ? winSignExp : macSignExp;
+
+ String signAct = si.getSignatureParts().iterator().next().
+ getSignatureDocument().getSignature().getSignatureValue().getStringValue();
+ assertEquals(signExp, signAct);
+ }
}
@Test
public void office2007prettyPrintedRels() throws Exception {
try (OPCPackage pkg = OPCPackage.open(testdata.getFile("office2007prettyPrintedRels.docx"), PackageAccess.READ)) {
SignatureConfig sic = new SignatureConfig();
- sic.setOpcPackage(pkg);
SignatureInfo si = new SignatureInfo();
+ si.setOpcPackage(pkg);
si.setSignatureConfig(sic);
boolean isValid = si.verifySignature();
assertTrue(isValid);
@@ -315,19 +304,19 @@ public class TestSignatureInfo {
};
for (String testFile : testFiles) {
- OPCPackage pkg = OPCPackage.open(testdata.getFile(testFile), PackageAccess.READ);
- SignatureConfig sic = new SignatureConfig();
- sic.setOpcPackage(pkg);
- SignatureInfo si = new SignatureInfo();
- si.setSignatureConfig(sic);
List<X509Certificate> result = new ArrayList<>();
- for (SignaturePart sp : si.getSignatureParts()) {
- if (sp.validate()) {
- result.add(sp.getSigner());
+ try (OPCPackage pkg = OPCPackage.open(testdata.getFile(testFile), PackageAccess.READ)) {
+ SignatureConfig sic = new SignatureConfig();
+ SignatureInfo si = new SignatureInfo();
+ si.setOpcPackage(pkg);
+ si.setSignatureConfig(sic);
+ for (SignaturePart sp : si.getSignatureParts()) {
+ if (sp.validate()) {
+ result.add(sp.getSigner());
+ }
}
+ pkg.revert();
}
- pkg.revert();
- pkg.close();
assertNotNull(result);
assertTrue(result.isEmpty());
}
@@ -345,14 +334,14 @@ public class TestSignatureInfo {
"ms-office-2010-signed.pptx",
"ms-office-2010-signed.xlsx",
"Office2010-SP1-XAdES-X-L.docx",
- "signed.docx",
+ "signed.docx"
};
for (String testFile : testFiles) {
try (OPCPackage pkg = OPCPackage.open(testdata.getFile(testFile), PackageAccess.READ)) {
SignatureConfig sic = new SignatureConfig();
- sic.setOpcPackage(pkg);
SignatureInfo si = new SignatureInfo();
+ si.setOpcPackage(pkg);
si.setSignatureConfig(sic);
List<X509Certificate> result = new ArrayList<>();
for (SignaturePart sp : si.getSignatureParts()) {
@@ -378,8 +367,8 @@ public class TestSignatureInfo {
String testFile = "hello-world-signed-twice.docx";
try (OPCPackage pkg = OPCPackage.open(testdata.getFile(testFile), PackageAccess.READ)) {
SignatureConfig sic = new SignatureConfig();
- sic.setOpcPackage(pkg);
SignatureInfo si = new SignatureInfo();
+ si.setOpcPackage(pkg);
si.setSignatureConfig(sic);
List<X509Certificate> result = new ArrayList<>();
for (SignaturePart sp : si.getSignatureParts()) {
@@ -404,9 +393,9 @@ public class TestSignatureInfo {
@Test
public void testSignSpreadsheet() throws Exception {
String testFile = "hello-world-unsigned.xlsx";
- OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE);
- sign(pkg, "Test", "CN=Test", 1);
- pkg.close();
+ try (OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE)) {
+ sign(pkg);
+ }
}
private static class CommitableWorkbook extends XSSFWorkbook {
@@ -423,7 +412,7 @@ public class TestSignatureInfo {
// sign & validate
String testFile = "hello-world-unsigned.xlsx";
try (OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE)) {
- sign(pkg, "Test", "CN=Test", 1);
+ sign(pkg);
// manipulate
try (CommitableWorkbook wb = new CommitableWorkbook(pkg)) {
@@ -436,8 +425,8 @@ public class TestSignatureInfo {
// validate
SignatureConfig sic = new SignatureConfig();
- sic.setOpcPackage(pkg);
SignatureInfo si = new SignatureInfo();
+ si.setOpcPackage(pkg);
si.setSignatureConfig(sic);
boolean b = si.verifySignature();
assertFalse("signature should be broken", b);
@@ -449,14 +438,14 @@ public class TestSignatureInfo {
@Test
public void testSignSpreadsheetWithSignatureInfo() throws Exception {
- initKeyPair("Test", "CN=Test");
+ initKeyPair();
String testFile = "hello-world-unsigned.xlsx";
try (OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE)) {
SignatureConfig sic = new SignatureConfig();
- sic.setOpcPackage(pkg);
sic.setKey(keyPair.getPrivate());
sic.setSigningCertificateChain(Collections.singletonList(x509));
SignatureInfo si = new SignatureInfo();
+ si.setOpcPackage(pkg);
si.setSignatureConfig(sic);
// hash > sha1 doesn't work in excel viewer ...
si.confirmSignature();
@@ -481,12 +470,11 @@ public class TestSignatureInfo {
try (OPCPackage pkg = OPCPackage.open(copy(sigCopy), PackageAccess.READ_WRITE)) {
- initKeyPair("Test", "CN=Test");
+ initKeyPair();
final X509CRL crl = generateCrl(x509, keyPair.getPrivate());
// setup
SignatureConfig signatureConfig = new SignatureConfig();
- signatureConfig.setOpcPackage(pkg);
signatureConfig.setKey(keyPair.getPrivate());
/*
@@ -529,17 +517,9 @@ public class TestSignatureInfo {
}
if (mockTsp) {
- TimeStampService tspService = new TimeStampService() {
- @Override
- public byte[] timeStamp(byte[] data, RevocationData revocationData) {
- revocationData.addCRL(crl);
- return "time-stamp-token".getBytes(LocaleUtil.CHARSET_1252);
- }
-
- @Override
- public void setSignatureConfig(SignatureConfig config) {
- // empty on purpose
- }
+ TimeStampService tspService = (signatureInfo, data, revocationData) -> {
+ revocationData.addCRL(crl);
+ return "time-stamp-token".getBytes(LocaleUtil.CHARSET_1252);
};
signatureConfig.setTspService(tspService);
} else {
@@ -555,8 +535,7 @@ public class TestSignatureInfo {
final RevocationData revocationData = new RevocationData();
revocationData.addCRL(crl);
- OCSPResp ocspResp = createOcspResp(x509, false,
- x509, x509, keyPair.getPrivate(), "SHA1withRSA", cal.getTimeInMillis());
+ OCSPResp ocspResp = createOcspResp(x509, x509, x509, keyPair.getPrivate(), cal.getTimeInMillis());
revocationData.addOCSP(ocspResp.getEncoded());
RevocationDataService revocationDataService = revocationChain -> revocationData;
@@ -564,33 +543,31 @@ public class TestSignatureInfo {
// operate
SignatureInfo si = new SignatureInfo();
+ si.setOpcPackage(pkg);
si.setSignatureConfig(signatureConfig);
try {
si.confirmSignature();
} catch (RuntimeException e) {
- pkg.close();
// only allow a ConnectException because of timeout, we see this in Jenkins from time to time...
if (e.getCause() == null) {
throw e;
}
if ((e.getCause() instanceof ConnectException) || (e.getCause() instanceof SocketTimeoutException)) {
Assume.assumeFalse("Only allowing ConnectException with 'timed out' as message here, but had: " + e,
- e.getCause().getMessage().contains("timed out"));
+ e.getCause().getMessage().contains("timed out"));
} else if (e.getCause() instanceof IOException) {
Assume.assumeFalse("Only allowing IOException with 'Error contacting TSP server' as message here, but had: " + e,
- e.getCause().getMessage().contains("Error contacting TSP server"));
+ e.getCause().getMessage().contains("Error contacting TSP server"));
} else if (e.getCause() instanceof RuntimeException) {
Assume.assumeFalse("Only allowing RuntimeException with 'This site is cur' as message here, but had: " + e,
- e.getCause().getMessage().contains("This site is cur"));
+ e.getCause().getMessage().contains("This site is cur"));
}
throw e;
}
// verify
Iterator<SignaturePart> spIter = si.getSignatureParts().iterator();
- assertTrue("Had: " + si.getSignatureConfig().getOpcPackage().
- getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN),
- spIter.hasNext());
+ assertTrue("Had: " + pkg.getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN), spIter.hasNext());
SignaturePart sp = spIter.next();
boolean valid = sp.validate();
assertTrue(valid);
@@ -627,10 +604,10 @@ public class TestSignatureInfo {
try (OPCPackage pkg = OPCPackage.open(new ByteArrayInputStream(bos.toByteArray()))) {
SignatureConfig signatureConfig = new SignatureConfig();
- signatureConfig.setOpcPackage(pkg);
signatureConfig.setUpdateConfigOnValidate(true);
SignatureInfo si = new SignatureInfo();
+ si.setOpcPackage(pkg);
si.setSignatureConfig(signatureConfig);
assertTrue(si.verifySignature());
@@ -667,13 +644,7 @@ public class TestSignatureInfo {
conn.connect();
if (fireRequest) {
- InputStream is = null;
- try {
- is = conn.getInputStream();
- } finally {
- IOUtils.closeQuietly(is);
- }
-
+ conn.getInputStream().close();
}
/* if connecting is possible we return true here */
return null;
@@ -692,9 +663,9 @@ public class TestSignatureInfo {
public void testCertChain() throws Exception {
KeyStore keystore = KeyStore.getInstance("PKCS12");
String password = "test";
- InputStream is = testdata.openResourceAsStream("chaintest.pfx");
- keystore.load(is, password.toCharArray());
- is.close();
+ try (InputStream is = testdata.openResourceAsStream("chaintest.pfx")) {
+ keystore.load(is, password.toCharArray());
+ }
Key key = keystore.getKey("poitest", password.toCharArray());
Certificate[] chainList = keystore.getCertificateChain("poitest");
@@ -714,9 +685,9 @@ public class TestSignatureInfo {
Calendar oldCal = LocaleUtil.getLocaleCalendar(2007, 7, 1);
signatureConfig.setExecutionTime(oldCal.getTime());
signatureConfig.setDigestAlgo(HashAlgorithm.sha1);
- signatureConfig.setOpcPackage(pkg);
SignatureInfo si = new SignatureInfo();
+ si.setOpcPackage(pkg);
si.setSignatureConfig(signatureConfig);
si.confirmSignature();
@@ -735,7 +706,7 @@ public class TestSignatureInfo {
@Test
public void testNonSha1() throws Exception {
String testFile = "hello-world-unsigned.xlsx";
- initKeyPair("Test", "CN=Test");
+ initKeyPair();
SignatureConfig signatureConfig = new SignatureConfig();
signatureConfig.setKey(keyPair.getPrivate());
@@ -745,13 +716,10 @@ public class TestSignatureInfo {
, HashAlgorithm.sha384, HashAlgorithm.sha512, HashAlgorithm.ripemd160};
for (HashAlgorithm ha : testAlgo) {
- OPCPackage pkg = null;
- try {
- signatureConfig.setDigestAlgo(ha);
- pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE);
- signatureConfig.setOpcPackage(pkg);
-
+ signatureConfig.setDigestAlgo(ha);
+ try (OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE)) {
SignatureInfo si = new SignatureInfo();
+ si.setOpcPackage(pkg);
si.setSignatureConfig(signatureConfig);
si.confirmSignature();
@@ -759,10 +727,6 @@ public class TestSignatureInfo {
assertTrue("Signature not correctly calculated for " + ha, b);
} catch (EncryptedDocumentException e) {
Assume.assumeTrue(e.getMessage().startsWith("Export Restrictions"));
- } finally {
- if (pkg != null) {
- pkg.close();
- }
}
}
}
@@ -776,20 +740,18 @@ public class TestSignatureInfo {
wb1.removeSheetAt(0);
ByteArrayOutputStream os = new ByteArrayOutputStream();
wb1.write(os);
- wb1.close();
- try (OPCPackage pkg = OPCPackage.open(new ByteArrayInputStream(os.toByteArray()))) {
- initKeyPair("Test", "CN=Test");
+ try (OPCPackage pkg = OPCPackage.open(new ByteArrayInputStream(os.toByteArray()))) {
+ initKeyPair();
SignatureConfig signatureConfig = new SignatureConfig();
signatureConfig.setKey(keyPair.getPrivate());
signatureConfig.setSigningCertificateChain(Collections.singletonList(x509));
- signatureConfig.setOpcPackage(pkg);
SignatureInfo si = new SignatureInfo();
+ si.setOpcPackage(pkg);
si.setSignatureConfig(signatureConfig);
si.confirmSignature();
assertTrue("invalid signature", si.verifySignature());
-
}
}
}
@@ -833,8 +795,8 @@ public class TestSignatureInfo {
private void verifyPkg63011(File tpl, boolean multi) throws InvalidFormatException, IOException {
try (OPCPackage pkg = OPCPackage.open(tpl, PackageAccess.READ)) {
SignatureConfig sic = new SignatureConfig();
- sic.setOpcPackage(pkg);
SignatureInfo si = new SignatureInfo();
+ si.setOpcPackage(pkg);
si.setSignatureConfig(sic);
List<X509Certificate> result = new ArrayList<>();
for (SignaturePart sp : si.getSignatureParts()) {
@@ -860,7 +822,7 @@ public class TestSignatureInfo {
}
private void signPkg63011(OPCPackage pkg, String pemFile, boolean multi)
- throws IOException, CertificateException, XMLSignatureException, MarshalException {
+ throws IOException, CertificateException, XMLSignatureException, MarshalException {
assertNotNull(pkg);
initKeyFromPEM(testdata.getFile(pemFile));
@@ -869,9 +831,9 @@ public class TestSignatureInfo {
config.setSigningCertificateChain(Collections.singletonList(x509));
config.setExecutionTime(cal.getTime());
config.setAllowMultipleSignatures(multi);
- config.setOpcPackage(pkg);
SignatureInfo si = new SignatureInfo();
+ si.setOpcPackage(pkg);
si.setSignatureConfig(config);
si.confirmSignature();
}
@@ -881,9 +843,9 @@ public class TestSignatureInfo {
SignatureConfig sic = new SignatureConfig();
final File file = testdata.getFile("PPT2016withComment.pptx");
try (final OPCPackage pkg = OPCPackage.open(file, PackageAccess.READ)) {
- sic.setOpcPackage(pkg);
sic.setUpdateConfigOnValidate(true);
SignatureInfo si = new SignatureInfo();
+ si.setOpcPackage(pkg);
si.setSignatureConfig(sic);
assertTrue(si.verifySignature());
}
@@ -897,8 +859,8 @@ public class TestSignatureInfo {
assertEquals(CanonicalizationMethod.INCLUSIVE, sic.getCanonicalizationMethod());
}
- private SignatureConfig prepareConfig(String alias, String signerDn, String pfxInput) throws Exception {
- initKeyPair(alias, signerDn, pfxInput);
+ private SignatureConfig prepareConfig(String pfxInput) throws Exception {
+ initKeyPair(pfxInput);
SignatureConfig signatureConfig = new SignatureConfig();
signatureConfig.setKey(keyPair.getPrivate());
@@ -909,11 +871,13 @@ public class TestSignatureInfo {
return signatureConfig;
}
- private void sign(OPCPackage pkgCopy, String alias, String signerDn, int signerCount) throws Exception {
- SignatureConfig signatureConfig = prepareConfig(alias, signerDn, null);
- signatureConfig.setOpcPackage(pkgCopy);
+ private void sign(OPCPackage pkgCopy) throws Exception {
+ int signerCount = 1;
+
+ SignatureConfig signatureConfig = prepareConfig(null);
SignatureInfo si = new SignatureInfo();
+ si.setOpcPackage(pkgCopy);
si.setSignatureConfig(signatureConfig);
final Document document = DocumentHelper.createDocument();
@@ -933,7 +897,7 @@ public class TestSignatureInfo {
si.postSign(xmlSignContext, signatureValue);
// verify: signature
- si.getSignatureConfig().setOpcPackage(pkgCopy);
+ si.setOpcPackage(pkgCopy);
List<X509Certificate> result = new ArrayList<>();
for (SignaturePart sp : si.getSignatureParts()) {
if (sp.validate()) {
@@ -943,24 +907,25 @@ public class TestSignatureInfo {
assertEquals(signerCount, result.size());
}
- private void initKeyPair(String alias, String subjectDN) throws Exception {
- initKeyPair(alias, subjectDN, null);
+ private void initKeyPair() throws Exception {
+ initKeyPair(null);
}
- private void initKeyPair(String alias, String subjectDN, String pfxInput) throws Exception {
+ private void initKeyPair(String pfxInput) throws Exception {
+ final String alias = "Test";
final char[] password = "test".toCharArray();
File file = new File("build/test.pfx");
KeyStore keystore = KeyStore.getInstance("PKCS12");
if (pfxInput != null) {
- InputStream fis = new ByteArrayInputStream(RawDataUtil.decompress(pfxInput));
- keystore.load(fis, password);
- fis.close();
+ try (InputStream fis = new ByteArrayInputStream(RawDataUtil.decompress(pfxInput))) {
+ keystore.load(fis, password);
+ }
} else if (file.exists()) {
- InputStream fis = new FileInputStream(file);
- keystore.load(fis, password);
- fis.close();
+ try (InputStream fis = new FileInputStream(file)) {
+ keystore.load(fis, password);
+ }
} else {
keystore.load(null, password);
}
@@ -977,15 +942,14 @@ public class TestSignatureInfo {
Date notAfter = cal2.getTime();
KeyUsage keyUsage = new KeyUsage(KeyUsage.digitalSignature);
- x509 = generateCertificate(keyPair.getPublic(), subjectDN
- , notBefore, notAfter, null, keyPair.getPrivate(), true, 0, null, null, keyUsage);
+ x509 = generateCertificate(keyPair.getPublic(), notBefore, notAfter, keyPair.getPrivate(), keyUsage);
keystore.setKeyEntry(alias, keyPair.getPrivate(), password, new Certificate[]{x509});
if (pfxInput == null) {
- FileOutputStream fos = new FileOutputStream(file);
- keystore.store(fos, password);
- fos.close();
+ try (FileOutputStream fos = new FileOutputStream(file)) {
+ keystore.store(fos, password);
+ }
}
}
}
@@ -1038,24 +1002,18 @@ public class TestSignatureInfo {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
SecureRandom random = new SecureRandom();
keyPairGenerator.initialize(new RSAKeyGenParameterSpec(1024,
- RSAKeyGenParameterSpec.F4), random);
+ RSAKeyGenParameterSpec.F4), random);
return keyPairGenerator.generateKeyPair();
}
private static X509Certificate generateCertificate(PublicKey subjectPublicKey,
- String subjectDn, Date notBefore, Date notAfter,
- X509Certificate issuerCertificate, PrivateKey issuerPrivateKey,
- boolean caFlag, int pathLength, String crlUri, String ocspUri,
- KeyUsage keyUsage)
- throws IOException, OperatorCreationException, CertificateException
- {
- String signatureAlgorithm = "SHA1withRSA";
- X500Name issuerName;
- if (issuerCertificate != null) {
- issuerName = new X509CertificateHolder(issuerCertificate.getEncoded()).getIssuer();
- } else {
- issuerName = new X500Name(subjectDn);
- }
+ Date notBefore, Date notAfter,
+ PrivateKey issuerPrivateKey,
+ KeyUsage keyUsage)
+ throws IOException, OperatorCreationException, CertificateException {
+ final String signatureAlgorithm = "SHA1withRSA";
+ final String subjectDn = "CN=Test";
+ X500Name issuerName = new X500Name(subjectDn);
RSAPublicKey rsaPubKey = (RSAPublicKey)subjectPublicKey;
RSAKeyParameters rsaSpec = new RSAKeyParameters(false, rsaPubKey.getModulus(), rsaPubKey.getPublicExponent());
@@ -1077,47 +1035,13 @@ public class TestSignatureInfo {
X509ExtensionUtils exUtils = new X509ExtensionUtils(digestCalc);
SubjectKeyIdentifier subKeyId = exUtils.createSubjectKeyIdentifier(subjectPublicKeyInfo);
- AuthorityKeyIdentifier autKeyId = (issuerCertificate != null)
- ? exUtils.createAuthorityKeyIdentifier(new X509CertificateHolder(issuerCertificate.getEncoded()))
- : exUtils.createAuthorityKeyIdentifier(subjectPublicKeyInfo);
+ AuthorityKeyIdentifier autKeyId = exUtils.createAuthorityKeyIdentifier(subjectPublicKeyInfo);
certificateGenerator.addExtension(Extension.subjectKeyIdentifier, false, subKeyId);
certificateGenerator.addExtension(Extension.authorityKeyIdentifier, false, autKeyId);
- if (caFlag) {
- BasicConstraints bc;
-
- if (-1 == pathLength) {
- bc = new BasicConstraints(true);
- } else {
- bc = new BasicConstraints(pathLength);
- }
- certificateGenerator.addExtension(Extension.basicConstraints, false, bc);
- }
-
- if (null != crlUri) {
- int uri = GeneralName.uniformResourceIdentifier;
- DERIA5String crlUriDer = new DERIA5String(crlUri);
- GeneralName gn = new GeneralName(uri, crlUriDer);
-
- DERSequence gnDer = new DERSequence(gn);
- GeneralNames gns = GeneralNames.getInstance(gnDer);
-
- DistributionPointName dpn = new DistributionPointName(0, gns);
- DistributionPoint distp = new DistributionPoint(dpn, null, null);
- DERSequence distpDer = new DERSequence(distp);
- certificateGenerator.addExtension(Extension.cRLDistributionPoints, false, distpDer);
- }
-
- if (null != ocspUri) {
- int uri = GeneralName.uniformResourceIdentifier;
- GeneralName ocspName = new GeneralName(uri, ocspUri);
-
- AuthorityInformationAccess authorityInformationAccess =
- new AuthorityInformationAccess(X509ObjectIdentifiers.ocspAccessMethod, ocspName);
-
- certificateGenerator.addExtension(Extension.authorityInfoAccess, false, authorityInformationAccess);
- }
+ BasicConstraints bc = new BasicConstraints(0);
+ certificateGenerator.addExtension(Extension.basicConstraints, false, bc);
if (null != keyUsage) {
certificateGenerator.addExtension(Extension.keyUsage, true, keyUsage);
@@ -1158,10 +1082,10 @@ public class TestSignatureInfo {
}
private static OCSPResp createOcspResp(X509Certificate certificate,
- boolean revoked, X509Certificate issuerCertificate,
- X509Certificate ocspResponderCertificate,
- PrivateKey ocspResponderPrivateKey, String signatureAlgorithm,
- long nonceTimeinMillis)
+ X509Certificate issuerCertificate,
+ X509Certificate ocspResponderCertificate,
+ PrivateKey ocspResponderPrivateKey,
+ long nonceTimeinMillis)
throws Exception {
DigestCalculator digestCalc = new JcaDigestCalculatorProviderBuilder()
.setProvider("BC").build().get(CertificateID.HASH_SHA1);
@@ -1192,9 +1116,6 @@ public class TestSignatureInfo {
for (Req ocspRequest : requestList) {
CertificateID certificateID = ocspRequest.getCertID();
CertificateStatus certificateStatus = CertificateStatus.GOOD;
- if (revoked) {
- certificateStatus = new RevokedStatus(new Date(), CRLReason.privilegeWithdrawn);
- }
basicOCSPRespBuilder.addResponse(certificateID, certificateStatus);
}