]> source.dussan.org Git - poi.git/commitdiff
#64186 - Decrease usage of ThreadLocals in XML Signature API
authorAndreas Beeker <kiwiwings@apache.org>
Sun, 1 Mar 2020 22:20:38 +0000 (22:20 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Sun, 1 Mar 2020 22:20:38 +0000 (22:20 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1874671 13f79535-47bb-0310-9956-ffa450edef68

17 files changed:
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/OOXMLURIDereferencer.java
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureMarshalDefaultListener.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureMarshalListener.java
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignaturePart.java
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/EnvelopedSignatureFacet.java
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/KeyInfoSignatureFacet.java
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/OOXMLSignatureFacet.java
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/Office2010SignatureFacet.java
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/SignatureFacet.java
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/SignatureFacetHelper.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESSignatureFacet.java
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESXLSignatureFacet.java
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampService.java
src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java

index b4061622e0c30ca42667664e44d2ccd775c920b2..b809b06ef5da1d0ce71f2b35aa539497f288e41c 100644 (file)
@@ -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);
     }
 }
index 0fcacaf376b32a9d50a8c6f76fc169831e641657..f122b36296935e6dde4c164a650d1544edcb574e 100644 (file)
@@ -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>
index c4f25f1222c57f7b2b21161600c2c375d471c0ee..806ab91d6509d0c91d824c74a6daea970ca903b1 100644 (file)
@@ -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 (file)
index 0000000..24acda2
--- /dev/null
@@ -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));
+        }
+    }
+}
index 017953f570ba4bd8f63bed40a07e8ea60d063ee7..34210f4cf5bee6e591b0cffaf9d85a8c76517fd4 100644 (file)
 
 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
index dab69bd2508fc70a509e811843aef8e51c256e75..d120d655e140840b797a30783b80d1157208adff 100644 (file)
@@ -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;
         }
index 12ba42c14c2262e1745c549433c9093c8bca5668..d37cc2ce773cf4b25fe98a4bea5f941fea8187fe 100644 (file)
 /* ====================================================================
    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);
     }
 }
index e7797e942d45e0428bacec5056de13cf2227fd5e..0943a8a596c5649ff30f2b6526ac361f5afb6758 100644 (file)
@@ -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");
index 5d4ccbd869af6218a743103553c58a785f112c27..0eff7e3186ccd2676a6c8087a992e9e6fa61cda7 100644 (file)
 
 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);
     }
 
index 59ba63c3da23666b3bf0538f513d4cbbd67b6a61..f9ea3a9662309ca81261a3d7b67aed2da612b54a 100644 (file)
@@ -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));
     }
index 29852f0044efcde8dbb2eaf9ef2b9e6807568cbd..cc1a803ce63a383403bfcb70dd5c7db1b7001bdd 100644 (file)
 /* ====================================================================
    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 (file)
index 0000000..e60771f
--- /dev/null
@@ -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);
+    }
+}
index c8f04e882407fa3f64a09dddb37a8c10593c6dc3..ce96f16a91f216a8f1734de08e1caec771a00c0d 100644 (file)
 /* ====================================================================
    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
      */
index e00de87b7c5c9e36dde0f21ea3a06ed76906a2f9..60b9e26e67621d83325de04987ecaa87708baa24 100644 (file)
@@ -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);
index c7fd85c46840db172d0be2b385549d954f35dc81..925f46307770e906b8e37ae51f104e9cace6ffba 100644 (file)
@@ -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
index ede39ac3577a19d449f29ccaf8737cfd911a956f..72561af9bd3392d072d3755f584a5db4eb322246 100644 (file)
 /* ====================================================================
    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;
 }
index e621f51e0d2a8f505ac2cb6c0b78be93c8e33c7a..1d9e15454286389169c208e50b6941815df4b2d4 100644 (file)
@@ -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);
         }