import org.apache.poi.openxml4j.opc.PackagePart;\r
import org.apache.poi.openxml4j.opc.PackagePartName;\r
import org.apache.poi.openxml4j.opc.PackagingURIHelper;\r
+import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable;\r
import org.apache.poi.util.POILogFactory;\r
import org.apache.poi.util.POILogger;\r
\r
/**\r
* JSR105 URI dereferencer for Office Open XML documents.\r
*/\r
-public class OOXMLURIDereferencer implements URIDereferencer {\r
+public class OOXMLURIDereferencer implements URIDereferencer, SignatureConfigurable {\r
\r
private static final POILogger LOG = POILogFactory.getLogger(OOXMLURIDereferencer.class);\r
\r
- private SignatureInfoConfig signatureConfig;\r
+ private SignatureConfig signatureConfig;\r
private URIDereferencer baseUriDereferencer;\r
\r
public OOXMLURIDereferencer() {\r
this.baseUriDereferencer = xmlSignatureFactory.getURIDereferencer();\r
}\r
\r
- public void setSignatureConfig(SignatureInfoConfig signatureConfig) {\r
+ public void setSignatureConfig(SignatureConfig signatureConfig) {\r
this.signatureConfig = signatureConfig;\r
}\r
\r
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.poifs.crypt.dsig;\r
+\r
+import java.security.PrivateKey;\r
+import java.security.cert.X509Certificate;\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.List;\r
+import java.util.UUID;\r
+\r
+import javax.xml.crypto.URIDereferencer;\r
+import javax.xml.crypto.dsig.CanonicalizationMethod;\r
+\r
+import org.apache.poi.EncryptedDocumentException;\r
+import org.apache.poi.openxml4j.opc.OPCPackage;\r
+import org.apache.poi.poifs.crypt.HashAlgorithm;\r
+import org.apache.poi.poifs.crypt.dsig.SignatureInfo.SignCreationListener;\r
+import org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet;\r
+import org.apache.poi.poifs.crypt.dsig.facets.OOXMLSignatureFacet;\r
+import org.apache.poi.poifs.crypt.dsig.facets.Office2010SignatureFacet;\r
+import org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet;\r
+import org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet;\r
+import org.apache.poi.poifs.crypt.dsig.services.RevocationDataService;\r
+import org.apache.poi.poifs.crypt.dsig.services.SignaturePolicyService;\r
+import org.apache.poi.poifs.crypt.dsig.services.TSPTimeStampService;\r
+import org.apache.poi.poifs.crypt.dsig.services.TimeStampService;\r
+import org.apache.poi.poifs.crypt.dsig.services.TimeStampServiceValidator;\r
+import org.apache.poi.poifs.crypt.dsig.spi.AddressDTO;\r
+import org.apache.poi.poifs.crypt.dsig.spi.IdentityDTO;\r
+import org.w3c.dom.events.EventListener;\r
+\r
+/**\r
+ * This class bundles the configuration options used for the existing\r
+ * signature facets.\r
+ * Apart of the opc-package (thread local) most values will probably be constant, so\r
+ * it might be configured centrally (e.g. by spring) \r
+ */\r
+public class SignatureConfig {\r
+ \r
+ public static interface SignatureConfigurable {\r
+ void setSignatureConfig(SignatureConfig signatureConfig); \r
+ }\r
+\r
+ private ThreadLocal<OPCPackage> opcPackage = new ThreadLocal<OPCPackage>();\r
+ \r
+ private List<SignatureFacet> signatureFacets = new ArrayList<SignatureFacet>();\r
+ private HashAlgorithm digestAlgo = HashAlgorithm.sha1;\r
+ private Date executionTime = new Date();\r
+ private PrivateKey key;\r
+ private List<X509Certificate> signingCertificateChain;\r
+ private IdentityDTO identity;\r
+ private AddressDTO address;\r
+ private byte[] photo;\r
+\r
+ /**\r
+ * the optional signature policy service used for XAdES-EPES.\r
+ */\r
+ private SignaturePolicyService signaturePolicyService;\r
+ private URIDereferencer uriDereferencer = new OOXMLURIDereferencer();\r
+ private String signatureNamespacePrefix;\r
+ private String canonicalizationMethod = CanonicalizationMethod.INCLUSIVE;\r
+ \r
+ private boolean includeEntireCertificateChain = true;\r
+ private boolean includeIssuerSerial = false;\r
+ private boolean includeKeyValue = false;\r
+ \r
+ private TimeStampService tspService = new TSPTimeStampService();\r
+ // timestamp service provider URL\r
+ private String tspUrl;\r
+ private boolean tspOldProtocol = false;\r
+ private HashAlgorithm tspDigestAlgo = HashAlgorithm.sha1;\r
+ private String tspUser;\r
+ private String tspPass;\r
+ private TimeStampServiceValidator tspValidator;\r
+ /**\r
+ * the optional TSP request policy OID.\r
+ */\r
+ private String tspRequestPolicy = "1.3.6.1.4.1.13762.3";\r
+ private String userAgent = "POI XmlSign Service TSP Client";\r
+ private String proxyUrl;\r
+ \r
+ /**\r
+ * the optional revocation data service used for XAdES-C and XAdES-X-L.\r
+ * When <code>null</code> the signature will be limited to XAdES-T only.\r
+ */\r
+ private RevocationDataService revocationDataService;\r
+ private HashAlgorithm xadesDigestAlgo = HashAlgorithm.sha1;\r
+ private String xadesRole = null;\r
+ private String xadesSignatureId = null;\r
+ private boolean xadesSignaturePolicyImplied = true;\r
+\r
+ /**\r
+ * Work-around for Office 2010 IssuerName encoding.\r
+ */\r
+ private boolean xadesIssuerNameNoReverseOrder = true;\r
+\r
+ /**\r
+ * The signature Id attribute value used to create the XML signature. A\r
+ * <code>null</code> value will trigger an automatically generated signature Id.\r
+ */\r
+ private String packageSignatureId = "idPackageSignature";\r
+ \r
+ /**\r
+ * Gives back the human-readable description of what the citizen will be\r
+ * signing. The default value is "Office OpenXML Document".\r
+ */\r
+ private String signatureDescription = "Office OpenXML Document";\r
+ \r
+ /**\r
+ * The process of signing includes the marshalling of xml structures.\r
+ * This also includes the canonicalization. Currently this leads to problems \r
+ * with certain namespaces, so this EventListener is used to interfere\r
+ * with the marshalling process.\r
+ */\r
+ EventListener signCreationListener = null;\r
+\r
+ protected void init(boolean onlyValidation) {\r
+ if (uriDereferencer == null) {\r
+ throw new EncryptedDocumentException("uriDereferencer is null");\r
+ }\r
+ if (opcPackage == null) {\r
+ throw new EncryptedDocumentException("opcPackage is null");\r
+ }\r
+ if (uriDereferencer instanceof SignatureConfigurable) {\r
+ ((SignatureConfigurable)uriDereferencer).setSignatureConfig(this);\r
+ }\r
+ if (onlyValidation) return;\r
+\r
+ if (signCreationListener == null) {\r
+ signCreationListener = new SignCreationListener();\r
+ }\r
+ \r
+ if (signCreationListener instanceof SignatureConfigurable) {\r
+ ((SignatureConfigurable)signCreationListener).setSignatureConfig(this);\r
+ }\r
+\r
+ \r
+ if (tspService != null) {\r
+ tspService.setSignatureConfig(this);\r
+ }\r
+ \r
+ if (xadesSignatureId == null || xadesSignatureId.isEmpty()) {\r
+ xadesSignatureId = "idSignedProperties";\r
+ }\r
+\r
+ if (signatureFacets.isEmpty()) {\r
+ addSignatureFacet(new OOXMLSignatureFacet());\r
+ addSignatureFacet(new KeyInfoSignatureFacet());\r
+ addSignatureFacet(new XAdESSignatureFacet());\r
+ addSignatureFacet(new Office2010SignatureFacet());\r
+ }\r
+\r
+ for (SignatureFacet sf : signatureFacets) {\r
+ sf.setSignatureConfig(this);\r
+ }\r
+ }\r
+ \r
+ public void addSignatureFacet(SignatureFacet sf) {\r
+ signatureFacets.add(sf);\r
+ }\r
+ \r
+ /**\r
+ * Gives back the used XAdES signature facet.\r
+ * \r
+ * @return\r
+ */\r
+ public XAdESSignatureFacet getXAdESSignatureFacet() {\r
+ for (SignatureFacet sf : getSignatureFacets()) {\r
+ if (sf instanceof XAdESSignatureFacet) {\r
+ return (XAdESSignatureFacet)sf;\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ \r
+ public List<SignatureFacet> getSignatureFacets() {\r
+ return signatureFacets;\r
+ }\r
+ public void setSignatureFacets(List<SignatureFacet> signatureFacets) {\r
+ this.signatureFacets = signatureFacets;\r
+ }\r
+ public HashAlgorithm getDigestAlgo() {\r
+ return digestAlgo;\r
+ }\r
+ public void setDigestAlgo(HashAlgorithm digestAlgo) {\r
+ this.digestAlgo = digestAlgo;\r
+ }\r
+ public OPCPackage getOpcPackage() {\r
+ return opcPackage.get();\r
+ }\r
+ public void setOpcPackage(OPCPackage opcPackage) {\r
+ this.opcPackage.set(opcPackage);\r
+ }\r
+ public PrivateKey getKey() {\r
+ return key;\r
+ }\r
+ public void setKey(PrivateKey key) {\r
+ this.key = key;\r
+ }\r
+ public List<X509Certificate> getSigningCertificateChain() {\r
+ return signingCertificateChain;\r
+ }\r
+ public void setSigningCertificateChain(\r
+ List<X509Certificate> signingCertificateChain) {\r
+ this.signingCertificateChain = signingCertificateChain;\r
+ }\r
+ public IdentityDTO getIdentity() {\r
+ return identity;\r
+ }\r
+ public void setIdentity(IdentityDTO identity) {\r
+ this.identity = identity;\r
+ }\r
+ public AddressDTO getAddress() {\r
+ return address;\r
+ }\r
+ public void setAddress(AddressDTO address) {\r
+ this.address = address;\r
+ }\r
+ public byte[] getPhoto() {\r
+ return photo;\r
+ }\r
+ public void setPhoto(byte[] photo) {\r
+ this.photo = photo;\r
+ }\r
+ public Date getExecutionTime() {\r
+ return executionTime;\r
+ }\r
+ public void setExecutionTime(Date executionTime) {\r
+ this.executionTime = executionTime;\r
+ }\r
+ public SignaturePolicyService getSignaturePolicyService() {\r
+ return signaturePolicyService;\r
+ }\r
+ public void setSignaturePolicyService(SignaturePolicyService signaturePolicyService) {\r
+ this.signaturePolicyService = signaturePolicyService;\r
+ }\r
+ public URIDereferencer getUriDereferencer() {\r
+ return uriDereferencer;\r
+ }\r
+ public void setUriDereferencer(URIDereferencer uriDereferencer) {\r
+ this.uriDereferencer = uriDereferencer;\r
+ }\r
+ public String getSignatureDescription() {\r
+ return signatureDescription;\r
+ }\r
+ public void setSignatureDescription(String signatureDescription) {\r
+ this.signatureDescription = signatureDescription;\r
+ }\r
+ public String getSignatureNamespacePrefix() {\r
+ return signatureNamespacePrefix;\r
+ }\r
+ public void setSignatureNamespacePrefix(String signatureNamespacePrefix) {\r
+ this.signatureNamespacePrefix = signatureNamespacePrefix;\r
+ }\r
+ public String getCanonicalizationMethod() {\r
+ return canonicalizationMethod;\r
+ }\r
+ public void setCanonicalizationMethod(String canonicalizationMethod) {\r
+ this.canonicalizationMethod = canonicalizationMethod;\r
+ }\r
+ public String getPackageSignatureId() {\r
+ return packageSignatureId;\r
+ }\r
+ public void setPackageSignatureId(String packageSignatureId) {\r
+ this.packageSignatureId = (packageSignatureId != null)\r
+ ? packageSignatureId\r
+ : "xmldsig-" + UUID.randomUUID();\r
+ }\r
+ public String getTspUrl() {\r
+ return tspUrl;\r
+ }\r
+ public void setTspUrl(String tspUrl) {\r
+ this.tspUrl = tspUrl;\r
+ }\r
+ public boolean isTspOldProtocol() {\r
+ return tspOldProtocol;\r
+ }\r
+ public void setTspOldProtocol(boolean tspOldProtocol) {\r
+ this.tspOldProtocol = tspOldProtocol;\r
+ }\r
+ public HashAlgorithm getTspDigestAlgo() {\r
+ return tspDigestAlgo;\r
+ }\r
+ public void setTspDigestAlgo(HashAlgorithm tspDigestAlgo) {\r
+ this.tspDigestAlgo = tspDigestAlgo;\r
+ }\r
+ public String getProxyUrl() {\r
+ return proxyUrl;\r
+ }\r
+ public void setProxyUrl(String proxyUrl) {\r
+ this.proxyUrl = proxyUrl;\r
+ }\r
+ public TimeStampService getTspService() {\r
+ return tspService;\r
+ }\r
+ public void setTspService(TimeStampService tspService) {\r
+ this.tspService = tspService;\r
+ }\r
+ public String getTspUser() {\r
+ return tspUser;\r
+ }\r
+ public void setTspUser(String tspUser) {\r
+ this.tspUser = tspUser;\r
+ }\r
+ public String getTspPass() {\r
+ return tspPass;\r
+ }\r
+ public void setTspPass(String tspPass) {\r
+ this.tspPass = tspPass;\r
+ }\r
+ public TimeStampServiceValidator getTspValidator() {\r
+ return tspValidator;\r
+ }\r
+ public void setTspValidator(TimeStampServiceValidator tspValidator) {\r
+ this.tspValidator = tspValidator;\r
+ }\r
+ public RevocationDataService getRevocationDataService() {\r
+ return revocationDataService;\r
+ }\r
+ public void setRevocationDataService(RevocationDataService revocationDataService) {\r
+ this.revocationDataService = revocationDataService;\r
+ }\r
+ public HashAlgorithm getXadesDigestAlgo() {\r
+ return xadesDigestAlgo;\r
+ }\r
+ public void setXadesDigestAlgo(HashAlgorithm xadesDigestAlgo) {\r
+ this.xadesDigestAlgo = xadesDigestAlgo;\r
+ }\r
+ public String getUserAgent() {\r
+ return userAgent;\r
+ }\r
+ public void setUserAgent(String userAgent) {\r
+ this.userAgent = userAgent;\r
+ }\r
+ public String getTspRequestPolicy() {\r
+ return tspRequestPolicy;\r
+ }\r
+ public void setTspRequestPolicy(String tspRequestPolicy) {\r
+ this.tspRequestPolicy = tspRequestPolicy;\r
+ }\r
+ public boolean isIncludeEntireCertificateChain() {\r
+ return includeEntireCertificateChain;\r
+ }\r
+ public void setIncludeEntireCertificateChain(boolean includeEntireCertificateChain) {\r
+ this.includeEntireCertificateChain = includeEntireCertificateChain;\r
+ }\r
+ public boolean isIncludeIssuerSerial() {\r
+ return includeIssuerSerial;\r
+ }\r
+ public void setIncludeIssuerSerial(boolean includeIssuerSerial) {\r
+ this.includeIssuerSerial = includeIssuerSerial;\r
+ }\r
+ public boolean isIncludeKeyValue() {\r
+ return includeKeyValue;\r
+ }\r
+ public void setIncludeKeyValue(boolean includeKeyValue) {\r
+ this.includeKeyValue = includeKeyValue;\r
+ }\r
+ public String getXadesRole() {\r
+ return xadesRole;\r
+ }\r
+ public void setXadesRole(String xadesRole) {\r
+ this.xadesRole = xadesRole;\r
+ }\r
+ public String getXadesSignatureId() {\r
+ return xadesSignatureId;\r
+ }\r
+ public void setXadesSignatureId(String xadesSignatureId) {\r
+ this.xadesSignatureId = xadesSignatureId;\r
+ }\r
+ public boolean isXadesSignaturePolicyImplied() {\r
+ return xadesSignaturePolicyImplied;\r
+ }\r
+ public void setXadesSignaturePolicyImplied(boolean xadesSignaturePolicyImplied) {\r
+ this.xadesSignaturePolicyImplied = xadesSignaturePolicyImplied;\r
+ }\r
+ public boolean isXadesIssuerNameNoReverseOrder() {\r
+ return xadesIssuerNameNoReverseOrder;\r
+ }\r
+ public void setXadesIssuerNameNoReverseOrder(boolean xadesIssuerNameNoReverseOrder) {\r
+ this.xadesIssuerNameNoReverseOrder = xadesIssuerNameNoReverseOrder;\r
+ }\r
+ public EventListener getSignCreationListener() {\r
+ return signCreationListener;\r
+ }\r
+ public void setSignCreationListener(EventListener signCreationListener) {\r
+ this.signCreationListener = signCreationListener;\r
+ }\r
+}\r
import org.apache.poi.poifs.crypt.ChainingMode;\r
import org.apache.poi.poifs.crypt.CipherAlgorithm;\r
import org.apache.poi.poifs.crypt.CryptoFunctions;\r
+import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable;\r
import org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet;\r
import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService;\r
import org.apache.poi.poifs.crypt.dsig.spi.DigestInfo;\r
import org.w3c.dom.events.MutationEvent;\r
import org.xml.sax.SAXException;\r
\r
-public class SignatureInfo {\r
+public class SignatureInfo implements SignatureConfigurable {\r
\r
public static final String XmlNS = "http://www.w3.org/2000/xmlns/";\r
public static final String XmlDSigNS = XMLSignature.XMLNS;\r
\r
+ // see https://www.ietf.org/rfc/rfc3110.txt\r
+ // RSA/SHA1 SIG Resource Records\r
public static final byte[] SHA1_DIGEST_INFO_PREFIX = new byte[]\r
{ 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14 };\r
\r
public static final byte[] RIPEMD256_DIGEST_INFO_PREFIX = new byte[]\r
{ 0x30, 0x2b, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x24, 0x03, 0x02, 0x03, 0x04, 0x20 };\r
\r
+ protected static class SignCreationListener implements EventListener, SignatureConfigurable {\r
+ ThreadLocal<EventTarget> target = new ThreadLocal<EventTarget>();\r
+ SignatureConfig signatureConfig;\r
+ public void setEventTarget(EventTarget target) {\r
+ this.target.set(target);\r
+ }\r
+ public void handleEvent(Event e) {\r
+ if (e instanceof MutationEvent) {\r
+ MutationEvent mutEvt = (MutationEvent)e;\r
+ if (mutEvt.getTarget() instanceof Element) {\r
+ Element el = (Element)mutEvt.getTarget();\r
+ String packageId = signatureConfig.getPackageSignatureId();\r
+ if (packageId.equals(el.getAttribute("Id"))) {\r
+ target.get().removeEventListener("DOMSubtreeModified", this, false);\r
+ el.setAttributeNS(XmlNS, "xmlns:mdssi", PackageNamespaces.DIGITAL_SIGNATURE);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ public void setSignatureConfig(SignatureConfig signatureConfig) {\r
+ this.signatureConfig = signatureConfig;\r
+ }\r
+ }\r
+ \r
\r
private static final POILogger LOG = POILogFactory.getLogger(SignatureInfo.class);\r
private static boolean isInitialized = false;\r
\r
- private SignatureInfoConfig signatureConfig;\r
+ private SignatureConfig signatureConfig;\r
\r
- public SignatureInfoConfig getSignatureConfig() {\r
+ public SignatureConfig getSignatureConfig() {\r
return signatureConfig;\r
}\r
\r
- public void setSignatureConfig(SignatureInfoConfig signatureConfig) {\r
+ public void setSignatureConfig(SignatureConfig signatureConfig) {\r
this.signatureConfig = signatureConfig;\r
}\r
\r
}\r
\r
protected boolean getSignersAndValidate(List<X509Certificate> signers, boolean onlyFirst) {\r
+ signatureConfig.init(true);\r
+ \r
boolean allValid = true;\r
List<PackagePart> signatureParts = getSignatureParts(onlyFirst);\r
if (signatureParts.isEmpty()) {\r
TransformerFactoryConfigurationError, TransformerException,\r
IOException, SAXException, NoSuchProviderException, XmlException, URISyntaxException {\r
SignatureInfo.initXmlProvider();\r
+ signatureConfig.init(false);\r
\r
// it's necessary to explicitly set the mdssi namespace, but the sign() method has no\r
// normal way to interfere with, so we need to add the namespace under the hand ...\r
- final EventTarget et = (EventTarget)document;\r
- EventListener myModificationListener = new EventListener() {\r
- @Override\r
- public void handleEvent(Event e) {\r
- if (e instanceof MutationEvent) {\r
- MutationEvent mutEvt = (MutationEvent)e;\r
- if (mutEvt.getTarget() instanceof Element) {\r
- Element el = (Element)mutEvt.getTarget();\r
- if ("idPackageObject".equals(el.getAttribute("Id"))) {\r
- et.removeEventListener("DOMSubtreeModified", this, false);\r
- el.setAttributeNS(XmlNS, "xmlns:mdssi", PackageNamespaces.DIGITAL_SIGNATURE);\r
- }\r
- }\r
- }\r
+ EventTarget target = (EventTarget)document;\r
+ EventListener creationListener = signatureConfig.getSignCreationListener();\r
+ if (creationListener != null) {\r
+ if (creationListener instanceof SignCreationListener) {\r
+ ((SignCreationListener)creationListener).setEventTarget(target);\r
}\r
- };\r
- \r
- et.addEventListener("DOMSubtreeModified", myModificationListener, false);\r
+ target.addEventListener("DOMSubtreeModified", creationListener, false);\r
+ }\r
\r
/*\r
* Signature context construction.\r
+++ /dev/null
-/* ====================================================================\r
- Licensed to the Apache Software Foundation (ASF) under one or more\r
- contributor license agreements. See the NOTICE file distributed with\r
- this work for additional information regarding copyright ownership.\r
- The ASF licenses this file to You under the Apache License, Version 2.0\r
- (the "License"); you may not use this file except in compliance with\r
- the License. You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.poifs.crypt.dsig;\r
-\r
-import java.security.PrivateKey;\r
-import java.security.cert.X509Certificate;\r
-import java.util.ArrayList;\r
-import java.util.Date;\r
-import java.util.List;\r
-import java.util.UUID;\r
-\r
-import javax.xml.crypto.URIDereferencer;\r
-import javax.xml.crypto.dsig.CanonicalizationMethod;\r
-\r
-import org.apache.poi.openxml4j.opc.OPCPackage;\r
-import org.apache.poi.poifs.crypt.HashAlgorithm;\r
-import org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet;\r
-import org.apache.poi.poifs.crypt.dsig.facets.OOXMLSignatureFacet;\r
-import org.apache.poi.poifs.crypt.dsig.facets.Office2010SignatureFacet;\r
-import org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet;\r
-import org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet;\r
-import org.apache.poi.poifs.crypt.dsig.services.SignaturePolicyService;\r
-import org.apache.poi.poifs.crypt.dsig.spi.AddressDTO;\r
-import org.apache.poi.poifs.crypt.dsig.spi.IdentityDTO;\r
-\r
-public class SignatureInfoConfig {\r
- \r
- private List<SignatureFacet> signatureFacets = new ArrayList<SignatureFacet>();\r
- private HashAlgorithm digestAlgo = HashAlgorithm.sha1;\r
- private Date executionTime = new Date();\r
- private OPCPackage opcPackage;\r
- private PrivateKey key;\r
- private List<X509Certificate> signingCertificateChain;\r
- private IdentityDTO identity;\r
- private AddressDTO address;\r
- private byte[] photo;\r
- private SignaturePolicyService signaturePolicyService;\r
- private URIDereferencer uriDereferencer;\r
- private String signatureNamespacePrefix;\r
- private String canonicalizationMethod = CanonicalizationMethod.INCLUSIVE;\r
-\r
- /**\r
- * The signature Id attribute value used to create the XML signature. A\r
- * <code>null</code> value will trigger an automatically generated signature Id.\r
- */\r
- private String packageSignatureId = "idPackageSignature";\r
- \r
- /**\r
- * Gives back the human-readable description of what the citizen will be\r
- * signing. The default value is "Office OpenXML Document".\r
- */\r
- private String signatureDescription = "Office OpenXML Document";\r
-\r
- public SignatureInfoConfig() {\r
- OOXMLURIDereferencer uriDereferencer = new OOXMLURIDereferencer();\r
- uriDereferencer.setSignatureConfig(this);\r
- this.uriDereferencer = uriDereferencer;\r
- }\r
- \r
- public void addSignatureFacet(SignatureFacet sf) {\r
- signatureFacets.add(sf);\r
- }\r
- \r
- public void addDefaultFacets() {\r
- addSignatureFacet(new OOXMLSignatureFacet(this));\r
- addSignatureFacet(new KeyInfoSignatureFacet(true, false, false));\r
-\r
- XAdESSignatureFacet xadesSignatureFacet = new XAdESSignatureFacet(this);\r
- xadesSignatureFacet.setIdSignedProperties("idSignedProperties");\r
- xadesSignatureFacet.setSignaturePolicyImplied(true);\r
- /*\r
- * Work-around for Office 2010.\r
- */\r
- xadesSignatureFacet.setIssuerNameNoReverseOrder(true);\r
- addSignatureFacet(xadesSignatureFacet);\r
- addSignatureFacet(new Office2010SignatureFacet());\r
- }\r
- \r
- /**\r
- * Gives back the used XAdES signature facet.\r
- * \r
- * @return\r
- */\r
- public XAdESSignatureFacet getXAdESSignatureFacet() {\r
- for (SignatureFacet sf : getSignatureFacets()) {\r
- if (sf instanceof XAdESSignatureFacet) {\r
- return (XAdESSignatureFacet)sf;\r
- }\r
- }\r
- return null;\r
- }\r
- \r
- \r
- public List<SignatureFacet> getSignatureFacets() {\r
- return signatureFacets;\r
- }\r
- public void setSignatureFacets(List<SignatureFacet> signatureFacets) {\r
- this.signatureFacets = signatureFacets;\r
- }\r
- public HashAlgorithm getDigestAlgo() {\r
- return digestAlgo;\r
- }\r
- public void setDigestAlgo(HashAlgorithm digestAlgo) {\r
- this.digestAlgo = digestAlgo;\r
- }\r
- public OPCPackage getOpcPackage() {\r
- return opcPackage;\r
- }\r
- public void setOpcPackage(OPCPackage opcPackage) {\r
- this.opcPackage = opcPackage;\r
- }\r
- public PrivateKey getKey() {\r
- return key;\r
- }\r
- public void setKey(PrivateKey key) {\r
- this.key = key;\r
- }\r
- public List<X509Certificate> getSigningCertificateChain() {\r
- return signingCertificateChain;\r
- }\r
- public void setSigningCertificateChain(\r
- List<X509Certificate> signingCertificateChain) {\r
- this.signingCertificateChain = signingCertificateChain;\r
- }\r
- public IdentityDTO getIdentity() {\r
- return identity;\r
- }\r
- public void setIdentity(IdentityDTO identity) {\r
- this.identity = identity;\r
- }\r
- public AddressDTO getAddress() {\r
- return address;\r
- }\r
- public void setAddress(AddressDTO address) {\r
- this.address = address;\r
- }\r
- public byte[] getPhoto() {\r
- return photo;\r
- }\r
- public void setPhoto(byte[] photo) {\r
- this.photo = photo;\r
- }\r
- public Date getExecutionTime() {\r
- return executionTime;\r
- }\r
- public void setExecutionTime(Date executionTime) {\r
- this.executionTime = executionTime;\r
- }\r
- public SignaturePolicyService getSignaturePolicyService() {\r
- return signaturePolicyService;\r
- }\r
- public void setSignaturePolicyService(SignaturePolicyService signaturePolicyService) {\r
- this.signaturePolicyService = signaturePolicyService;\r
- }\r
- public URIDereferencer getUriDereferencer() {\r
- return uriDereferencer;\r
- }\r
- public void setUriDereferencer(URIDereferencer uriDereferencer) {\r
- this.uriDereferencer = uriDereferencer;\r
- }\r
- public String getSignatureDescription() {\r
- return signatureDescription;\r
- }\r
- public void setSignatureDescription(String signatureDescription) {\r
- this.signatureDescription = signatureDescription;\r
- }\r
- public String getSignatureNamespacePrefix() {\r
- return signatureNamespacePrefix;\r
- }\r
- public void setSignatureNamespacePrefix(String signatureNamespacePrefix) {\r
- this.signatureNamespacePrefix = signatureNamespacePrefix;\r
- }\r
- public String getCanonicalizationMethod() {\r
- return canonicalizationMethod;\r
- }\r
- public void setCanonicalizationMethod(String canonicalizationMethod) {\r
- this.canonicalizationMethod = canonicalizationMethod;\r
- }\r
- public String getPackageSignatureId() {\r
- return packageSignatureId;\r
- }\r
- public void setPackageSignatureId(String packageSignatureId) {\r
- this.packageSignatureId = (packageSignatureId != null)\r
- ? packageSignatureId\r
- : "xmldsig-" + UUID.randomUUID();\r
- }\r
-}\r
import javax.xml.crypto.dsig.XMLSignatureFactory;\r
import javax.xml.crypto.dsig.spec.TransformParameterSpec;\r
\r
-import org.apache.poi.poifs.crypt.dsig.SignatureInfoConfig;\r
+import org.apache.poi.poifs.crypt.dsig.SignatureConfig;\r
import org.w3c.dom.Document;\r
\r
/**\r
*/\r
public class EnvelopedSignatureFacet implements SignatureFacet {\r
\r
- private SignatureInfoConfig signatureConfig;\r
+ private SignatureConfig signatureConfig;\r
\r
- public EnvelopedSignatureFacet(SignatureInfoConfig signatureConfig) {\r
+ public void setSignatureConfig(SignatureConfig signatureConfig) {\r
this.signatureConfig = signatureConfig;\r
}\r
-\r
+ \r
@Override\r
public void postSign(Document document, List<X509Certificate> signingCertificateChain) {\r
// empty\r
import javax.xml.crypto.dsig.keyinfo.X509Data;\r
\r
import org.apache.jcp.xml.dsig.internal.dom.DOMKeyInfo;\r
+import org.apache.poi.poifs.crypt.dsig.SignatureConfig;\r
import org.apache.poi.poifs.crypt.dsig.SignatureInfo;\r
import org.apache.poi.util.POILogFactory;\r
import org.apache.poi.util.POILogger;\r
public class KeyInfoSignatureFacet implements SignatureFacet {\r
\r
private static final POILogger LOG = POILogFactory.getLogger(KeyInfoSignatureFacet.class);\r
+ \r
+ SignatureConfig signatureConfig;\r
\r
- private final boolean includeEntireCertificateChain;\r
-\r
- private final boolean includeIssuerSerial;\r
-\r
- private final boolean includeKeyValue;\r
-\r
- /**\r
- * Main constructor.\r
- * \r
- * @param includeEntireCertificateChain\r
- * @param includeIssuerSerial\r
- * @param includeKeyValue\r
- */\r
- public KeyInfoSignatureFacet(boolean includeEntireCertificateChain,\r
- boolean includeIssuerSerial, boolean includeKeyValue) {\r
- this.includeEntireCertificateChain = includeEntireCertificateChain;\r
- this.includeIssuerSerial = includeIssuerSerial;\r
- this.includeKeyValue = includeKeyValue;\r
+ public void setSignatureConfig(SignatureConfig signatureConfig) {\r
+ this.signatureConfig = signatureConfig;\r
}\r
\r
@Override\r
\r
List<Object> keyInfoContent = new ArrayList<Object>();\r
\r
- if (this.includeKeyValue) {\r
+ if (signatureConfig.isIncludeKeyValue()) {\r
KeyValue keyValue;\r
try {\r
keyValue = keyInfoFactory.newKeyValue(signingCertificate.getPublicKey());\r
keyInfoContent.add(keyValue);\r
}\r
\r
- if (this.includeIssuerSerial) {\r
+ if (signatureConfig.isIncludeIssuerSerial()) {\r
x509DataObjects.add(keyInfoFactory.newX509IssuerSerial(\r
signingCertificate.getIssuerX500Principal().toString(),\r
signingCertificate.getSerialNumber()));\r
}\r
\r
- if (this.includeEntireCertificateChain) {\r
+ if (signatureConfig.isIncludeEntireCertificateChain()) {\r
x509DataObjects.addAll(signingCertificateChain);\r
} else {\r
x509DataObjects.add(signingCertificate);\r
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;\r
import org.apache.poi.openxml4j.opc.PackagingURIHelper;\r
import org.apache.poi.openxml4j.opc.TargetMode;\r
-import org.apache.poi.poifs.crypt.dsig.SignatureInfoConfig;\r
+import org.apache.poi.poifs.crypt.dsig.SignatureConfig;\r
import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService;\r
import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService.RelationshipTransformParameterSpec;\r
import org.apache.poi.util.POILogFactory;\r
public static final String OOXML_DIGSIG_NS = "http://schemas.openxmlformats.org/package/2006/digital-signature";\r
public static final String OFFICE_DIGSIG_NS = "http://schemas.microsoft.com/office/2006/digsig";\r
\r
- private final SignatureInfoConfig signatureConfig;\r
+ private SignatureConfig signatureConfig;\r
\r
- /**\r
- * Main constructor.\r
- */\r
- public OOXMLSignatureFacet(SignatureInfoConfig signatureConfig) {\r
+ public void setSignatureConfig(SignatureConfig signatureConfig) {\r
this.signatureConfig = signatureConfig;\r
}\r
-\r
+ \r
@Override\r
public void preSign(\r
Document document\r
import javax.xml.crypto.dsig.XMLObject;\r
import javax.xml.crypto.dsig.XMLSignatureFactory;\r
\r
+import org.apache.poi.poifs.crypt.dsig.SignatureConfig;\r
import org.apache.xmlbeans.XmlException;\r
import org.etsi.uri.x01903.v13.QualifyingPropertiesType;\r
import org.etsi.uri.x01903.v13.UnsignedPropertiesType;\r
*/\r
public class Office2010SignatureFacet implements SignatureFacet {\r
\r
+ public void setSignatureConfig(SignatureConfig signatureConfig) {\r
+ // this.signatureConfig = signatureConfig;\r
+ }\r
+ \r
@Override\r
public void preSign(\r
Document document\r
import javax.xml.crypto.dsig.XMLObject;\r
import javax.xml.crypto.dsig.XMLSignatureFactory;\r
\r
+import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable;\r
import org.apache.xmlbeans.XmlException;\r
import org.w3c.dom.Document;\r
\r
* @author Frank Cornelis\r
* \r
*/\r
-public interface SignatureFacet {\r
+public interface SignatureFacet extends SignatureConfigurable {\r
\r
/**\r
* This method is being invoked by the XML signature service engine during\r
\r
import org.apache.poi.poifs.crypt.CryptoFunctions;\r
import org.apache.poi.poifs.crypt.HashAlgorithm;\r
+import org.apache.poi.poifs.crypt.dsig.SignatureConfig;\r
import org.apache.poi.poifs.crypt.dsig.SignatureInfo;\r
-import org.apache.poi.poifs.crypt.dsig.SignatureInfoConfig;\r
import org.apache.poi.poifs.crypt.dsig.services.SignaturePolicyService;\r
import org.apache.poi.util.POILogFactory;\r
import org.apache.poi.util.POILogger;\r
\r
private static final String XADES_TYPE = "http://uri.etsi.org/01903#SignedProperties";\r
\r
- private SignatureInfoConfig signatureConfig;\r
+ private SignatureConfig signatureConfig;\r
\r
- private String idSignedProperties;\r
-\r
- private boolean signaturePolicyImplied;\r
-\r
- private String role;\r
-\r
- private boolean issuerNameNoReverseOrder = false;\r
-\r
private Map<String, String> dataObjectFormatMimeTypes = new HashMap<String, String>();\r
\r
- /**\r
- * Main constructor.\r
- * \r
- * @param clock\r
- * the clock to be used for determining the xades:SigningTime,\r
- * defaults to now when null\r
- * @param hashAlgo\r
- * the digest algorithm to be used for all required XAdES digest\r
- * operations. Possible values: "SHA-1", "SHA-256", or "SHA-512",\r
- * defaults to SHA-1 when null\r
- * @param signaturePolicyService\r
- * the optional signature policy service used for XAdES-EPES.\r
- */\r
- public XAdESSignatureFacet(SignatureInfoConfig signatureConfig) {\r
+ public void setSignatureConfig(SignatureConfig signatureConfig) {\r
this.signatureConfig = signatureConfig;\r
}\r
\r
\r
// SignedProperties\r
SignedPropertiesType signedProperties = qualifyingProperties.addNewSignedProperties();\r
- String signedPropertiesId = this.idSignedProperties;\r
- if (this.idSignedProperties == null) {\r
- signedPropertiesId = signatureConfig.getPackageSignatureId() + "-xades";\r
- }\r
- signedProperties.setId(signedPropertiesId);\r
+ signedProperties.setId(signatureConfig.getXadesSignatureId());\r
\r
// SignedSignatureProperties\r
SignedSignaturePropertiesType signedSignatureProperties = signedProperties.addNewSignedSignatureProperties();\r
// SigningTime\r
Calendar xmlGregorianCalendar = Calendar.getInstance();\r
xmlGregorianCalendar.setTimeZone(TimeZone.getTimeZone("Z"));\r
- xmlGregorianCalendar.setTime(this.signatureConfig.getExecutionTime());\r
+ xmlGregorianCalendar.setTime(signatureConfig.getExecutionTime());\r
xmlGregorianCalendar.clear(Calendar.MILLISECOND);\r
signedSignatureProperties.setSigningTime(xmlGregorianCalendar);\r
\r
}\r
CertIDListType signingCertificates = signedSignatureProperties.addNewSigningCertificate();\r
CertIDType certId = signingCertificates.addNewCert();\r
- X509Certificate signingCertificate = signatureConfig.getSigningCertificateChain().get(0);\r
- setCertID(certId, signingCertificate, this.signatureConfig.getDigestAlgo(), this.issuerNameNoReverseOrder);\r
+ X509Certificate certificate = signatureConfig.getSigningCertificateChain().get(0);\r
+ setCertID(certId, signatureConfig, signatureConfig.isXadesIssuerNameNoReverseOrder(), certificate);\r
\r
// ClaimedRole\r
- if (null != this.role && false == this.role.isEmpty()) {\r
+ String role = signatureConfig.getXadesRole();\r
+ if (role != null && !role.isEmpty()) {\r
SignerRoleType signerRole = signedSignatureProperties.addNewSignerRole();\r
signedSignatureProperties.setSignerRole(signerRole);\r
ClaimedRolesListType claimedRolesList = signerRole.addNewClaimedRoles();\r
AnyType claimedRole = claimedRolesList.addNewClaimedRole();\r
XmlString roleString = XmlString.Factory.newInstance();\r
- roleString.setStringValue(this.role);\r
+ roleString.setStringValue(role);\r
insertXChild(claimedRole, roleString);\r
}\r
\r
// XAdES-EPES\r
- SignaturePolicyService policyService = this.signatureConfig.getSignaturePolicyService();\r
+ SignaturePolicyService policyService = signatureConfig.getSignaturePolicyService();\r
if (policyService != null) {\r
SignaturePolicyIdentifierType signaturePolicyIdentifier =\r
signedSignatureProperties.addNewSignaturePolicyIdentifier();\r
\r
byte[] signaturePolicyDocumentData = policyService.getSignaturePolicyDocument();\r
DigestAlgAndValueType sigPolicyHash = signaturePolicyId.addNewSigPolicyHash();\r
- setDigestAlgAndValue(sigPolicyHash, signaturePolicyDocumentData, this.signatureConfig.getDigestAlgo());\r
+ setDigestAlgAndValue(sigPolicyHash, signaturePolicyDocumentData, signatureConfig.getDigestAlgo());\r
\r
String signaturePolicyDownloadUrl = policyService.getSignaturePolicyDownloadUrl();\r
if (null != signaturePolicyDownloadUrl) {\r
spUriElement.setStringValue(signaturePolicyDownloadUrl);\r
insertXChild(sigPolicyQualifier, spUriElement);\r
}\r
- } else if (this.signaturePolicyImplied) {\r
+ } else if (signatureConfig.isXadesSignaturePolicyImplied()) {\r
SignaturePolicyIdentifierType signaturePolicyIdentifier = \r
signedSignatureProperties.addNewSignaturePolicyIdentifier();\r
signaturePolicyIdentifier.addNewSignaturePolicyImplied();\r
}\r
\r
// DataObjectFormat\r
- if (false == this.dataObjectFormatMimeTypes.isEmpty()) {\r
+ if (!dataObjectFormatMimeTypes.isEmpty()) {\r
SignedDataObjectPropertiesType signedDataObjectProperties =\r
signedProperties.addNewSignedDataObjectProperties();\r
\r
objects.add(xadesObject);\r
\r
// add XAdES ds:Reference\r
- DigestMethod digestMethod = signatureFactory.newDigestMethod(this.signatureConfig.getDigestAlgo().xmlSignUri, null);\r
+ DigestMethod digestMethod = signatureFactory.newDigestMethod(signatureConfig.getDigestAlgo().xmlSignUri, null);\r
List<Transform> transforms = new ArrayList<Transform>();\r
Transform exclusiveTransform = signatureFactory\r
.newTransform(CanonicalizationMethod.INCLUSIVE,\r
(TransformParameterSpec) null);\r
transforms.add(exclusiveTransform);\r
- Reference reference = signatureFactory.newReference("#"\r
- + signedPropertiesId, digestMethod, transforms, XADES_TYPE,\r
- null);\r
+ Reference reference = signatureFactory.newReference\r
+ ("#"+signatureConfig.getXadesSignatureId(), digestMethod, transforms, XADES_TYPE, null);\r
references.add(reference);\r
}\r
\r
\r
/**\r
* Gives back the JAXB CertID data structure.\r
- * \r
- * @param certificate\r
- * @param xadesObjectFactory\r
- * @param xmldsigObjectFactory\r
- * @param digestAlgorithm\r
- * @return\r
*/\r
- protected static void setCertID(\r
- CertIDType certId,\r
- X509Certificate certificate,\r
- HashAlgorithm digestAlgorithm, boolean issuerNameNoReverseOrder) {\r
+ protected static void setCertID\r
+ (CertIDType certId, SignatureConfig signatureConfig, boolean issuerNameNoReverseOrder, X509Certificate certificate) {\r
X509IssuerSerialType issuerSerial = certId.addNewIssuerSerial();\r
String issuerName;\r
if (issuerNameNoReverseOrder) {\r
+ e.getMessage(), e);\r
}\r
DigestAlgAndValueType certDigest = certId.addNewCertDigest(); \r
- setDigestAlgAndValue(certDigest, encodedCertificate, digestAlgorithm);\r
+ setDigestAlgAndValue(certDigest, encodedCertificate, signatureConfig.getXadesDigestAlgo());\r
}\r
\r
/**\r
this.dataObjectFormatMimeTypes.put(dsReferenceUri, mimetype);\r
}\r
\r
- /**\r
- * Sets the Id that will be used on the SignedProperties element;\r
- * \r
- * @param idSignedProperties\r
- */\r
- public void setIdSignedProperties(String idSignedProperties) {\r
- this.idSignedProperties = idSignedProperties;\r
- }\r
-\r
- /**\r
- * Sets the signature policy to implied.\r
- * \r
- * @param signaturePolicyImplied\r
- */\r
- public void setSignaturePolicyImplied(boolean signaturePolicyImplied) {\r
- this.signaturePolicyImplied = signaturePolicyImplied;\r
- }\r
-\r
- /**\r
- * Sets the XAdES claimed role.\r
- * \r
- * @param role\r
- */\r
- public void setRole(String role) {\r
- this.role = role;\r
- }\r
-\r
- /**\r
- * Work-around for Office 2010 IssuerName encoding.\r
- * \r
- * @param reverseOrder\r
- */\r
- public void setIssuerNameNoReverseOrder(boolean reverseOrder) {\r
- this.issuerNameNoReverseOrder = reverseOrder;\r
- }\r
-\r
-\r
public Map<String,String> getNamespacePrefixMapping() {\r
Map<String,String> map = new HashMap<String,String>();\r
map.put("xd", "http://uri.etsi.org/01903/v1.3.2#");\r
import javax.xml.crypto.dsig.XMLObject;\r
import javax.xml.crypto.dsig.XMLSignatureFactory;\r
\r
-import org.apache.poi.poifs.crypt.HashAlgorithm;\r
+import org.apache.poi.poifs.crypt.dsig.SignatureConfig;\r
import org.apache.poi.poifs.crypt.dsig.services.RevocationData;\r
-import org.apache.poi.poifs.crypt.dsig.services.RevocationDataService;\r
-import org.apache.poi.poifs.crypt.dsig.services.TimeStampService;\r
import org.apache.poi.util.POILogFactory;\r
import org.apache.poi.util.POILogger;\r
import org.apache.xml.security.c14n.Canonicalizer;\r
public static final String XADES_NAMESPACE = "http://uri.etsi.org/01903/v1.3.2#";\r
\r
public static final String XADES141_NAMESPACE = "http://uri.etsi.org/01903/v1.4.1#";\r
+ \r
+ private SignatureConfig signatureConfig;\r
\r
- private final TimeStampService timeStampService;\r
-\r
- private String c14nAlgoId;\r
-\r
- private final RevocationDataService revocationDataService;\r
+ private String c14nAlgoId = CanonicalizationMethod.EXCLUSIVE;\r
\r
private final CertificateFactory certificateFactory;\r
\r
- private final HashAlgorithm hashAlgo;\r
-\r
- /**\r
- * Convenience constructor.\r
- * \r
- * @param timeStampService\r
- * the time-stamp service used for XAdES-T and XAdES-X.\r
- * @param revocationDataService\r
- * the optional revocation data service used for XAdES-C and\r
- * XAdES-X-L. When <code>null</code> the signature will be\r
- * limited to XAdES-T only.\r
- */\r
- public XAdESXLSignatureFacet(TimeStampService timeStampService,\r
- RevocationDataService revocationDataService) {\r
- this(timeStampService, revocationDataService, HashAlgorithm.sha1);\r
+ public void setSignatureConfig(SignatureConfig signatureConfig) {\r
+ this.signatureConfig = signatureConfig;\r
}\r
+ \r
\r
+ \r
/**\r
- * Main constructor.\r
+ * Convenience constructor.\r
* \r
* @param timeStampService\r
* the time-stamp service used for XAdES-T and XAdES-X.\r
* @param revocationDataService\r
- * the optional revocation data service used for XAdES-C and\r
- * XAdES-X-L. When <code>null</code> the signature will be\r
- * limited to XAdES-T only.\r
- * @param digestAlgorithm\r
- * the digest algorithm to be used for construction of the\r
- * XAdES-X-L elements.\r
*/\r
- public XAdESXLSignatureFacet(TimeStampService timeStampService,\r
- RevocationDataService revocationDataService,\r
- HashAlgorithm digestAlgorithm) {\r
- this.c14nAlgoId = CanonicalizationMethod.EXCLUSIVE;\r
- this.hashAlgo = digestAlgorithm;\r
- this.timeStampService = timeStampService;\r
- this.revocationDataService = revocationDataService;\r
-\r
+ public XAdESXLSignatureFacet() {\r
try {\r
this.certificateFactory = CertificateFactory.getInstance("X.509");\r
} catch (CertificateException e) {\r
\r
RevocationData tsaRevocationDataXadesT = new RevocationData();\r
LOG.log(POILogger.DEBUG, "creating XAdES-T time-stamp");\r
- XAdESTimeStampType signatureTimeStamp = createXAdESTimeStamp(\r
- Collections.singletonList(nlSigVal.item(0)), tsaRevocationDataXadesT, this.c14nAlgoId, this.timeStampService);\r
+ XAdESTimeStampType signatureTimeStamp = createXAdESTimeStamp\r
+ (Collections.singletonList(nlSigVal.item(0)), tsaRevocationDataXadesT);\r
\r
// marshal the XAdES-T extension\r
unsignedSigProps.addNewSignatureTimeStamp().set(signatureTimeStamp);\r
insertXChild(unsignedSigProps, validationData);\r
}\r
\r
- if (null == this.revocationDataService) {\r
+ if (signatureConfig.getRevocationDataService() == null) {\r
/*\r
* Without revocation data service we cannot construct the XAdES-C\r
* extension.\r
unsignedSigProps.addNewCompleteCertificateRefs();\r
\r
CertIDListType certIdList = completeCertificateRefs.addNewCertRefs();\r
- for (int certIdx = 1; certIdx < signingCertificateChain.size(); certIdx++) {\r
- /*\r
- * We skip the signing certificate itself according to section\r
- * 4.4.3.2 of the XAdES 1.4.1 specification.\r
- */\r
- X509Certificate certificate = signingCertificateChain.get(certIdx);\r
- CertIDType certId = certIdList.addNewCert();\r
- XAdESSignatureFacet.setCertID(certId, certificate, this.hashAlgo, false);\r
+ /*\r
+ * We skip the signing certificate itself according to section\r
+ * 4.4.3.2 of the XAdES 1.4.1 specification.\r
+ */\r
+ int chainSize = signingCertificateChain.size();\r
+ if (chainSize > 1) {\r
+ for (X509Certificate cert : signingCertificateChain.subList(1, chainSize)) {\r
+ CertIDType certId = certIdList.addNewCert();\r
+ XAdESSignatureFacet.setCertID(certId, signatureConfig, false, cert);\r
+ }\r
}\r
\r
// XAdES-C: complete revocation refs\r
CompleteRevocationRefsType completeRevocationRefs = \r
unsignedSigProps.addNewCompleteRevocationRefs();\r
- RevocationData revocationData = this.revocationDataService\r
- .getRevocationData(signingCertificateChain);\r
+ RevocationData revocationData = signatureConfig.getRevocationDataService()\r
+ .getRevocationData(signingCertificateChain);\r
if (revocationData.hasCRLs()) {\r
CRLRefsType crlRefs = completeRevocationRefs.addNewCRLRefs();\r
completeRevocationRefs.setCRLRefs(crlRefs);\r
crlIdentifier.setNumber(getCrlNumber(crl));\r
\r
DigestAlgAndValueType digestAlgAndValue = crlRef.addNewDigestAlgAndValue();\r
- XAdESSignatureFacet.setDigestAlgAndValue(digestAlgAndValue, encodedCrl, this.hashAlgo);\r
+ XAdESSignatureFacet.setDigestAlgAndValue(digestAlgAndValue, encodedCrl, signatureConfig.getDigestAlgo());\r
}\r
}\r
if (revocationData.hasOCSPs()) {\r
OCSPRefType ocspRef = ocspRefs.addNewOCSPRef();\r
\r
DigestAlgAndValueType digestAlgAndValue = ocspRef.addNewDigestAlgAndValue();\r
- XAdESSignatureFacet.setDigestAlgAndValue(digestAlgAndValue, ocsp, this.hashAlgo);\r
+ XAdESSignatureFacet.setDigestAlgAndValue(digestAlgAndValue, ocsp, signatureConfig.getDigestAlgo());\r
\r
OCSPIdentifierType ocspIdentifier = ocspRef.addNewOCSPIdentifier();\r
\r
\r
RevocationData tsaRevocationDataXadesX1 = new RevocationData();\r
LOG.log(POILogger.DEBUG, "creating XAdES-X time-stamp");\r
- XAdESTimeStampType timeStampXadesX1 = createXAdESTimeStamp(\r
- timeStampNodesXadesX1, tsaRevocationDataXadesX1,\r
- this.c14nAlgoId, this.timeStampService);\r
+ XAdESTimeStampType timeStampXadesX1 = createXAdESTimeStamp\r
+ (timeStampNodesXadesX1, tsaRevocationDataXadesX1);\r
if (tsaRevocationDataXadesX1.hasRevocationDataEntries()) {\r
ValidationDataType timeStampXadesX1ValidationData = createValidationData(tsaRevocationDataXadesX1);\r
insertXChild(unsignedSigProps, timeStampXadesX1ValidationData);\r
}\r
}\r
\r
- public static XAdESTimeStampType createXAdESTimeStamp(\r
+ private XAdESTimeStampType createXAdESTimeStamp(\r
List<Node> nodeList,\r
- RevocationData revocationData,\r
- String c14nAlgoId,\r
- TimeStampService timeStampService) {\r
+ RevocationData revocationData) {\r
byte[] c14nSignatureValueElement = getC14nValue(nodeList, c14nAlgoId);\r
\r
- return createXAdESTimeStamp(c14nSignatureValueElement, revocationData,\r
- c14nAlgoId, timeStampService);\r
+ return createXAdESTimeStamp(c14nSignatureValueElement, revocationData);\r
}\r
\r
- public static XAdESTimeStampType createXAdESTimeStamp(\r
- byte[] data,\r
- RevocationData revocationData,\r
- String c14nAlgoId,\r
- TimeStampService timeStampService) {\r
+ private XAdESTimeStampType createXAdESTimeStamp(byte[] data, RevocationData revocationData) {\r
// create the time-stamp\r
byte[] timeStampToken;\r
try {\r
- timeStampToken = timeStampService.timeStamp(data, revocationData);\r
+ timeStampToken = signatureConfig.getTspService().timeStamp(data, revocationData);\r
} catch (Exception e) {\r
throw new RuntimeException("error while creating a time-stamp: "\r
+ e.getMessage(), e);\r
package org.apache.poi.poifs.crypt.dsig.services;\r
\r
import java.io.ByteArrayOutputStream;\r
+import java.io.IOException;\r
import java.io.OutputStream;\r
import java.math.BigInteger;\r
import java.net.HttpURLConnection;\r
\r
import org.apache.poi.poifs.crypt.CryptoFunctions;\r
import org.apache.poi.poifs.crypt.HashAlgorithm;\r
+import org.apache.poi.poifs.crypt.dsig.SignatureConfig;\r
import org.apache.poi.util.IOUtils;\r
import org.apache.poi.util.POILogFactory;\r
import org.apache.poi.util.POILogger;\r
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;\r
import org.bouncycastle.asn1.cmp.PKIFailureInfo;\r
+import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;\r
import org.bouncycastle.asn1.x500.X500Name;\r
+import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;\r
import org.bouncycastle.cert.X509CertificateHolder;\r
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;\r
-import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;\r
import org.bouncycastle.cms.DefaultCMSSignatureAlgorithmNameGenerator;\r
import org.bouncycastle.cms.SignerId;\r
import org.bouncycastle.cms.SignerInformationVerifier;\r
\r
private static final POILogger LOG = POILogFactory.getLogger(TSPTimeStampService.class);\r
\r
- static {\r
- CryptoFunctions.registerBouncyCastle();\r
- }\r
-\r
- public static final String DEFAULT_USER_AGENT = "POI XmlSign Service TSP Client";\r
-\r
- private final String tspServiceUrl;\r
-\r
- private String requestPolicy;\r
-\r
- private final String userAgent;\r
-\r
- private final TimeStampServiceValidator validator;\r
-\r
- private String username;\r
-\r
- private String password;\r
-\r
- private String proxyHost;\r
-\r
- private int proxyPort;\r
-\r
- private HashAlgorithm digestAlgo;\r
-\r
- private String digestAlgoOid;\r
-\r
- private String requestContentType = "application/timestamp-query;charset=ISO-8859-1";\r
-\r
- private String responseContentType = "application/timestamp-reply";\r
- \r
- public TSPTimeStampService(String tspServiceUrl,\r
- TimeStampServiceValidator validator) {\r
- this(tspServiceUrl, validator, null, null);\r
- }\r
-\r
- /**\r
- * Main constructor.\r
- * \r
- * @param tspServiceUrl\r
- * the URL of the TSP service.\r
- * @param validator\r
- * the trust validator used to validate incoming TSP response\r
- * signatures.\r
- * @param requestPolicy\r
- * the optional TSP request policy.\r
- * @param userAgent\r
- * the optional User-Agent TSP request header value.\r
- */\r
- public TSPTimeStampService(String tspServiceUrl,\r
- TimeStampServiceValidator validator, String requestPolicy,\r
- String userAgent) {\r
- if (null == tspServiceUrl) {\r
- throw new IllegalArgumentException("TSP service URL required");\r
- }\r
- this.tspServiceUrl = tspServiceUrl;\r
-\r
- if (null == validator) {\r
- throw new IllegalArgumentException("TSP validator required");\r
- }\r
- this.validator = validator;\r
-\r
- this.requestPolicy = requestPolicy;\r
-\r
- if (null != userAgent) {\r
- this.userAgent = userAgent;\r
- } else {\r
- this.userAgent = DEFAULT_USER_AGENT;\r
- }\r
- \r
- setDigestAlgo(HashAlgorithm.sha1);\r
- }\r
-\r
- /**\r
- * Sets the request policy OID.\r
- * \r
- * @param policyOid\r
- */\r
- public void setRequestPolicy(String policyOid) {\r
- this.requestPolicy = policyOid;\r
- }\r
-\r
- /**\r
- * Sets the credentials used in case the TSP service requires\r
- * authentication.\r
- * \r
- * @param username\r
- * @param password\r
- */\r
- public void setAuthenticationCredentials(String username, String password) {\r
- this.username = username;\r
- this.password = password;\r
- }\r
-\r
- /**\r
- * Resets the authentication credentials.\r
- */\r
- public void resetAuthenticationCredentials() {\r
- this.username = null;\r
- this.password = null;\r
- }\r
+ private SignatureConfig signatureConfig;\r
\r
/**\r
- * Sets the digest algorithm used for time-stamping data. Example value:\r
- * "SHA-1".\r
- * \r
- * @param digestAlgo\r
+ * Maps the digest algorithm to corresponding OID value.\r
*/\r
- public void setDigestAlgo(HashAlgorithm digestAlgo) {\r
+ public ASN1ObjectIdentifier mapDigestAlgoToOID(HashAlgorithm digestAlgo) {\r
switch (digestAlgo) {\r
- case sha1:\r
- digestAlgoOid = "1.3.14.3.2.26";\r
- break;\r
- case sha256:\r
- digestAlgoOid = "2.16.840.1.101.3.4.2.1";\r
- break;\r
- case sha384:\r
- digestAlgoOid = "2.16.840.1.101.3.4.2.2";\r
- break;\r
- case sha512:\r
- digestAlgoOid = "2.16.840.1.101.3.4.2.3";\r
- break;\r
+ case sha1: return X509ObjectIdentifiers.id_SHA1;\r
+ case sha256: return NISTObjectIdentifiers.id_sha256;\r
+ case sha384: return NISTObjectIdentifiers.id_sha384;\r
+ case sha512: return NISTObjectIdentifiers.id_sha512;\r
default:\r
throw new IllegalArgumentException("unsupported digest algo: " + digestAlgo);\r
}\r
-\r
- this.digestAlgo = digestAlgo;\r
- }\r
-\r
- /**\r
- * Configures the HTTP proxy settings to be used to connect to the TSP\r
- * service.\r
- * \r
- * @param proxyHost\r
- * @param proxyPort\r
- */\r
- public void setProxy(String proxyHost, int proxyPort) {\r
- this.proxyHost = proxyHost;\r
- this.proxyPort = proxyPort;\r
- }\r
-\r
- /**\r
- * Resets the HTTP proxy settings.\r
- */\r
- public void resetProxy() {\r
- this.proxyHost = null;\r
- this.proxyPort = 0;\r
}\r
\r
+ @SuppressWarnings("unchecked")\r
public byte[] timeStamp(byte[] data, RevocationData revocationData)\r
throws Exception {\r
// digest the message\r
- MessageDigest messageDigest = CryptoFunctions.getMessageDigest(this.digestAlgo);\r
+ MessageDigest messageDigest = CryptoFunctions.getMessageDigest(signatureConfig.getTspDigestAlgo());\r
byte[] digest = messageDigest.digest(data);\r
\r
// generate the TSP request\r
BigInteger nonce = new BigInteger(128, new SecureRandom());\r
TimeStampRequestGenerator requestGenerator = new TimeStampRequestGenerator();\r
requestGenerator.setCertReq(true);\r
- if (null != this.requestPolicy) {\r
- requestGenerator.setReqPolicy(this.requestPolicy);\r
+ String requestPolicy = signatureConfig.getTspRequestPolicy();\r
+ if (requestPolicy != null) {\r
+ requestGenerator.setReqPolicy(new ASN1ObjectIdentifier(requestPolicy));\r
}\r
- TimeStampRequest request = requestGenerator.generate(this.digestAlgoOid, digest, nonce);\r
+ ASN1ObjectIdentifier digestAlgoOid = mapDigestAlgoToOID(signatureConfig.getTspDigestAlgo());\r
+ TimeStampRequest request = requestGenerator.generate(digestAlgoOid, digest, nonce);\r
byte[] encodedRequest = request.getEncoded();\r
\r
// create the HTTP POST request\r
- Proxy proxy = (this.proxyHost != null)\r
- ? new Proxy(Proxy.Type.HTTP, new InetSocketAddress(this.proxyHost, this.proxyPort))\r
- : Proxy.NO_PROXY;\r
- HttpURLConnection huc = (HttpURLConnection)new URL(this.tspServiceUrl).openConnection(proxy);\r
+ Proxy proxy = Proxy.NO_PROXY;\r
+ if (signatureConfig.getProxyUrl() != null) {\r
+ URL proxyUrl = new URL(signatureConfig.getProxyUrl());\r
+ String host = proxyUrl.getHost();\r
+ int port = proxyUrl.getPort();\r
+ proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, (port == -1 ? 80 : port)));\r
+ }\r
+ \r
+ HttpURLConnection huc = (HttpURLConnection)new URL(signatureConfig.getTspUrl()).openConnection(proxy);\r
\r
- if (null != this.username) {\r
- String userPassword = this.username + ":" + this.password;\r
+ if (signatureConfig.getTspUser() != null) {\r
+ String userPassword = signatureConfig.getTspUser() + ":" + signatureConfig.getTspPass();\r
String encoding = DatatypeConverter.printBase64Binary(userPassword.getBytes(Charset.forName("iso-8859-1")));\r
huc.setRequestProperty("Authorization", "Basic " + encoding);\r
}\r
\r
huc.setDoOutput(true); // also sets method to POST.\r
- huc.setRequestProperty("User-Agent", this.userAgent);\r
- huc.setRequestProperty("Content-Type", requestContentType);\r
+ huc.setRequestProperty("User-Agent", signatureConfig.getUserAgent());\r
+ huc.setRequestProperty("Content-Type", signatureConfig.isTspOldProtocol()\r
+ ? "application/timestamp-request"\r
+ : "application/timestamp-query;charset=ISO-8859-1");\r
\r
OutputStream hucOut = huc.getOutputStream();\r
hucOut.write(encodedRequest);\r
\r
int statusCode = huc.getResponseCode();\r
if (statusCode != 200) {\r
- LOG.log(POILogger.ERROR, "Error contacting TSP server ", this.tspServiceUrl);\r
- throw new Exception("Error contacting TSP server " + this.tspServiceUrl);\r
+ LOG.log(POILogger.ERROR, "Error contacting TSP server ", signatureConfig.getTspUrl());\r
+ throw new IOException("Error contacting TSP server " + signatureConfig.getTspUrl());\r
}\r
\r
// HTTP input validation\r
IOUtils.copy(huc.getInputStream(), bos);\r
LOG.log(POILogger.DEBUG, "response content: ", bos.toString());\r
\r
- if (!contentType.startsWith(responseContentType)) {\r
+ if (!contentType.startsWith(signatureConfig.isTspOldProtocol() \r
+ ? "application/timestamp-response"\r
+ : "application/timestamp-reply"\r
+ )) {\r
throw new RuntimeException("invalid Content-Type: " + contentType);\r
}\r
\r
\r
// TSP signer certificates retrieval\r
Collection<X509CertificateHolder> certificates = timeStampToken.getCertificates().getMatches(null);\r
- JcaX509ExtensionUtils utils = new JcaX509ExtensionUtils();\r
\r
X509CertificateHolder signerCert = null;\r
Map<X500Name, X509CertificateHolder> certificateMap = new HashMap<X500Name, X509CertificateHolder>();\r
}\r
\r
// TSP signer cert path building\r
- if (null == signerCert) {\r
- throw new RuntimeException(\r
- "TSP response token has no signer certificate");\r
+ if (signerCert == null) {\r
+ throw new RuntimeException("TSP response token has no signer certificate");\r
}\r
List<X509Certificate> tspCertificateChain = new ArrayList<X509Certificate>();\r
JcaX509CertificateConverter x509converter = new JcaX509CertificateConverter();\r
timeStampToken.validate(verifier);\r
\r
// verify TSP signer certificate\r
- this.validator.validate(tspCertificateChain, revocationData);\r
+ if (signatureConfig.getTspValidator() != null) {\r
+ signatureConfig.getTspValidator().validate(tspCertificateChain, revocationData);\r
+ }\r
\r
LOG.log(POILogger.DEBUG, "time-stamp token time: "\r
+ timeStampToken.getTimeStampInfo().getGenTime());\r
return timestamp;\r
}\r
\r
- /**\r
- * usually the request content type is "application/timestamp-query;charset=ISO-8859-1",\r
- * but some timestamp server use a different content type\r
- */\r
- public void setRequestContentType(String requestContentType) {\r
- this.requestContentType = requestContentType;\r
- }\r
-\r
- /**\r
- * usually the response content type is "application/timestamp-reply",\r
- * but some timestamp server use a different content type\r
- */\r
- public void setResponseContentType(String responseContentType) {\r
- this.responseContentType = responseContentType;\r
+ public void setSignatureConfig(SignatureConfig signatureConfig) {\r
+ this.signatureConfig = signatureConfig;\r
}\r
}
\ No newline at end of file
\r
package org.apache.poi.poifs.crypt.dsig.services;\r
\r
+import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable;\r
+\r
\r
/**\r
* Interface for a time-stamp service.\r
* @author Frank Cornelis\r
* \r
*/\r
-public interface TimeStampService {\r
+public interface TimeStampService extends SignatureConfigurable {\r
\r
/**\r
* Gives back the encoded time-stamp token for the given array of data\r
import org.apache.poi.POIDataSamples;\r
import org.apache.poi.openxml4j.opc.OPCPackage;\r
import org.apache.poi.openxml4j.opc.PackageAccess;\r
+import org.apache.poi.poifs.crypt.dsig.SignatureConfig;\r
import org.apache.poi.poifs.crypt.dsig.SignatureInfo;\r
-import org.apache.poi.poifs.crypt.dsig.SignatureInfoConfig;\r
import org.apache.poi.poifs.crypt.dsig.facets.EnvelopedSignatureFacet;\r
import org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet;\r
import org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet;\r
import org.apache.poi.poifs.crypt.dsig.facets.XAdESXLSignatureFacet;\r
import org.apache.poi.poifs.crypt.dsig.services.RevocationData;\r
import org.apache.poi.poifs.crypt.dsig.services.RevocationDataService;\r
-import org.apache.poi.poifs.crypt.dsig.services.TSPTimeStampService;\r
import org.apache.poi.poifs.crypt.dsig.services.TimeStampService;\r
import org.apache.poi.poifs.crypt.dsig.services.TimeStampServiceValidator;\r
import org.apache.poi.poifs.crypt.dsig.spi.DigestInfo;\r
cal.setTimeZone(TimeZone.getTimeZone("UTC"));\r
cal.set(2014, 7, 6, 21, 42, 12);\r
}\r
- \r
+\r
@Test\r
public void getSignerUnsigned() throws Exception {\r
String testFiles[] = { \r
\r
for (String testFile : testFiles) {\r
OPCPackage pkg = OPCPackage.open(testdata.getFile(testFile), PackageAccess.READ);\r
- SignatureInfoConfig sic = new SignatureInfoConfig();\r
+ SignatureConfig sic = new SignatureConfig();\r
sic.setOpcPackage(pkg);\r
SignatureInfo si = new SignatureInfo();\r
si.setSignatureConfig(sic);\r
\r
for (String testFile : testFiles) {\r
OPCPackage pkg = OPCPackage.open(testdata.getFile(testFile), PackageAccess.READ);\r
- SignatureInfoConfig sic = new SignatureInfoConfig();\r
+ SignatureConfig sic = new SignatureConfig();\r
sic.setOpcPackage(pkg);\r
SignatureInfo si = new SignatureInfo();\r
si.setSignatureConfig(sic);\r
public void getMultiSigners() throws Exception {\r
String testFile = "hello-world-signed-twice.docx";\r
OPCPackage pkg = OPCPackage.open(testdata.getFile(testFile), PackageAccess.READ);\r
- SignatureInfoConfig sic = new SignatureInfoConfig();\r
+ SignatureConfig sic = new SignatureConfig();\r
sic.setOpcPackage(pkg);\r
SignatureInfo si = new SignatureInfo();\r
si.setSignatureConfig(sic);\r
initKeyPair("Test", "CN=Test");\r
String testFile = "hello-world-unsigned.xlsx";\r
OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE);\r
- SignatureInfoConfig sic = new SignatureInfoConfig();\r
+ SignatureConfig sic = new SignatureConfig();\r
sic.setOpcPackage(pkg);\r
sic.setKey(keyPair.getPrivate());\r
sic.setSigningCertificateChain(Collections.singletonList(x509));\r
- sic.addDefaultFacets();\r
SignatureInfo si = new SignatureInfo();\r
si.setSignatureConfig(sic);\r
// hash > sha1 doesn't work in excel viewer ...\r
final X509CRL crl = PkiTestUtils.generateCrl(x509, keyPair.getPrivate());\r
\r
// setup\r
- SignatureInfoConfig signatureConfig = new SignatureInfoConfig();\r
+ SignatureConfig signatureConfig = new SignatureConfig();\r
signatureConfig.setOpcPackage(pkg);\r
signatureConfig.setKey(keyPair.getPrivate());\r
\r
certificateChain.add(x509);\r
signatureConfig.setSigningCertificateChain(certificateChain);\r
\r
- signatureConfig.addSignatureFacet(new EnvelopedSignatureFacet(signatureConfig));\r
- signatureConfig.addSignatureFacet(new KeyInfoSignatureFacet(true, false, false));\r
- signatureConfig.addSignatureFacet(new XAdESSignatureFacet(signatureConfig));\r
+ signatureConfig.addSignatureFacet(new EnvelopedSignatureFacet());\r
+ signatureConfig.addSignatureFacet(new KeyInfoSignatureFacet());\r
+ signatureConfig.addSignatureFacet(new XAdESSignatureFacet());\r
+ signatureConfig.addSignatureFacet(new XAdESXLSignatureFacet());\r
\r
-\r
+ boolean mockTsp = false;\r
// http://timestamping.edelweb.fr/service/tsp\r
// http://tsa.belgium.be/connect\r
- String tspServiceUrl = "http://timestamping.edelweb.fr/service/tsp";\r
+ signatureConfig.setTspUrl("http://timestamping.edelweb.fr/service/tsp");\r
+ signatureConfig.setTspOldProtocol(true);\r
\r
- TimeStampService timeStampService;\r
- if (tspServiceUrl == null) {\r
- timeStampService = new TimeStampService(){\r
+ if (mockTsp) {\r
+ TimeStampService tspService = new TimeStampService(){\r
public byte[] timeStamp(byte[] data, RevocationData revocationData) throws Exception {\r
revocationData.addCRL(crl);\r
return "time-stamp-token".getBytes(); \r
}\r
+ public void setSignatureConfig(SignatureConfig config) {}\r
};\r
+ signatureConfig.setTspService(tspService);\r
} else {\r
TimeStampServiceValidator tspValidator = new TimeStampServiceValidator() {\r
@Override\r
}\r
}\r
};\r
- \r
- TSPTimeStampService tspService = new TSPTimeStampService(tspServiceUrl, tspValidator);\r
- if (tspServiceUrl.contains("edelweb")) {\r
- tspService.setRequestContentType("application/timestamp-request");\r
- tspService.setResponseContentType("application/timestamp-response");\r
- }\r
- timeStampService = tspService;\r
+ signatureConfig.setTspValidator(tspValidator);\r
+ signatureConfig.setTspOldProtocol(signatureConfig.getTspUrl().contains("edelweb"));\r
}\r
\r
final RevocationData revocationData = new RevocationData();\r
return revocationData;\r
}\r
};\r
+ signatureConfig.setRevocationDataService(revocationDataService);\r
\r
- XAdESXLSignatureFacet xadesXLSignatureFacet = new XAdESXLSignatureFacet(\r
- timeStampService, revocationDataService);\r
SignatureInfo si = new SignatureInfo();\r
si.setSignatureConfig(signatureConfig);\r
\r
private OPCPackage sign(OPCPackage pkgCopy, String alias, String signerDn, int signerCount) throws Exception {\r
initKeyPair(alias, signerDn);\r
\r
- SignatureInfoConfig signatureConfig = new SignatureInfoConfig();\r
+ SignatureConfig signatureConfig = new SignatureConfig();\r
signatureConfig.setKey(keyPair.getPrivate());\r
signatureConfig.setSigningCertificateChain(Collections.singletonList(x509));\r
signatureConfig.setExecutionTime(cal.getTime());\r
signatureConfig.setDigestAlgo(HashAlgorithm.sha1);\r
signatureConfig.setOpcPackage(pkgCopy);\r
- signatureConfig.addDefaultFacets();\r
\r
SignatureInfo si = new SignatureInfo();\r
si.setSignatureConfig(signatureConfig);\r