/* ====================================================================
   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.facets.SignatureFacet.OO_DIGSIG_NS;
import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.XADES_132_NS;

import java.security.PrivateKey;
import java.security.Provider;
import java.security.cert.X509Certificate;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
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 javax.xml.crypto.URIDereferencer;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;

import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet;
import org.apache.poi.poifs.crypt.dsig.facets.OOXMLSignatureFacet;
import org.apache.poi.poifs.crypt.dsig.facets.Office2010SignatureFacet;
import org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet;
import org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet;
import org.apache.poi.poifs.crypt.dsig.services.RevocationDataService;
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.LocaleUtil;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.xml.security.signature.XMLSignature;
import org.w3c.dom.events.EventListener;

This class bundles the configuration options used for the existing signature facets. Apart of the thread local members (e.g. opc-package) most values will probably be constant, so it might be configured centrally (e.g. by spring)
/** * This class bundles the configuration options used for the existing * signature facets. * Apart of the thread local members (e.g. opc-package) most values will probably be constant, so * it might be configured centrally (e.g. by spring) */
@SuppressWarnings({"unused","WeakerAccess"}) public class SignatureConfig { public static final String SIGNATURE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; 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"; public interface SignatureConfigurable { void setSignatureConfig(SignatureConfig signatureConfig); } private ThreadLocal<OPCPackage> opcPackage = new ThreadLocal<>(); private ThreadLocal<XMLSignatureFactory> signatureFactory = new ThreadLocal<>(); private ThreadLocal<KeyInfoFactory> keyInfoFactory = new ThreadLocal<>(); private ThreadLocal<Provider> provider = new ThreadLocal<>(); private List<SignatureFacet> signatureFacets = new ArrayList<>(); private HashAlgorithm digestAlgo = HashAlgorithm.sha256; private Date executionTime = new Date(); private PrivateKey key; private List<X509Certificate> signingCertificateChain;
the optional signature policy service used for XAdES-EPES.
/** * the optional signature policy service used for XAdES-EPES. */
private SignaturePolicyService signaturePolicyService; private URIDereferencer uriDereferencer; private String canonicalizationMethod = CanonicalizationMethod.INCLUSIVE; private boolean includeEntireCertificateChain = true; private boolean includeIssuerSerial; private boolean includeKeyValue;
the time-stamp service used for XAdES-T and XAdES-X.
/** * the time-stamp service used for XAdES-T and XAdES-X. */
private TimeStampService tspService = new TSPTimeStampService();
timestamp service provider URL
/** * timestamp service provider URL */
private String tspUrl; private boolean tspOldProtocol;
if not defined, it's the same as the main digest
/** * if not defined, it's the same as the main digest */
private HashAlgorithm tspDigestAlgo; private String tspUser; private String tspPass; private TimeStampServiceValidator tspValidator;
the optional TSP request policy OID.
/** * the optional TSP request policy OID. */
private String tspRequestPolicy = "1.3.6.1.4.1.13762.3"; private String userAgent = "POI XmlSign Service TSP Client"; private String proxyUrl;
the optional revocation data service used for XAdES-C and XAdES-X-L. When null the signature will be limited to XAdES-T only.
/** * the optional revocation data service used for XAdES-C and XAdES-X-L. * When <code>null</code> the signature will be limited to XAdES-T only. */
private RevocationDataService revocationDataService;
if not defined, it's the same as the main digest
/** * if not defined, it's the same as the main digest */
private HashAlgorithm xadesDigestAlgo; private String xadesRole; private String xadesSignatureId = "idSignedProperties"; private boolean xadesSignaturePolicyImplied = true; private String xadesCanonicalizationMethod = CanonicalizationMethod.EXCLUSIVE;
Work-around for Office 2010 IssuerName encoding.
/** * Work-around for Office 2010 IssuerName encoding. */
private boolean xadesIssuerNameNoReverseOrder = true;
The signature Id attribute value used to create the XML signature. A null value will trigger an automatically generated signature Id.
/** * The signature Id attribute value used to create the XML signature. A * <code>null</code> value will trigger an automatically generated signature Id. */
private String packageSignatureId = "idPackageSignature";
Gives back the human-readable description of what the citizen will be signing. The default value is "Office OpenXML Document".
/** * Gives back the human-readable description of what the citizen will be * signing. The default value is "Office OpenXML Document". */
private String signatureDescription = "Office OpenXML Document";
The process of signing includes the marshalling of xml structures. This also includes the canonicalization. Currently this leads to problems with certain namespaces, so this EventListener is used to interfere with the marshalling process.
/** * The process of signing includes the marshalling of xml structures. * This also includes the canonicalization. Currently this leads to problems * with certain namespaces, so this EventListener is used to interfere * with the marshalling process. */
private EventListener signatureMarshalListener;
Map of namespace uris to prefix If a mapping is specified, the corresponding elements will be prefixed
/** * Map of namespace uris to prefix * If a mapping is specified, the corresponding elements will be prefixed */
private final Map<String,String> namespacePrefixes = new HashMap<>();
if true, the signature config is updated based on the validated document
/** * if true, the signature config is updated based on the validated document */
private boolean updateConfigOnValidate = false;
if true, the signature is added to the existing signatures
Since:POI 4.1.0
/** * if true, the signature is added to the existing signatures * * @since POI 4.1.0 */
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.
Params:
  • 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
/** * 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); } }
Params:
  • signatureFacet – the signature facet is appended to facet list
/** * @param signatureFacet the signature facet is appended to facet list */
public void addSignatureFacet(SignatureFacet signatureFacet) { signatureFacets.add(signatureFacet); }
Returns:the list of facets, may be empty when the config object is not initialized
/** * @return the list of facets, may be empty when the config object is not initialized */
public List<SignatureFacet> getSignatureFacets() { return signatureFacets; }
Params:
  • signatureFacets – the new list of facets
/** * @param signatureFacets the new list of facets */
public void setSignatureFacets(List<SignatureFacet> signatureFacets) { this.signatureFacets = signatureFacets; }
Returns:the main digest algorithm, defaults to sha256
/** * @return the main digest algorithm, defaults to sha256 */
public HashAlgorithm getDigestAlgo() { return digestAlgo; }
Params:
  • digestAlgo – the main digest algorithm
/** * @param digestAlgo the main digest algorithm */
public void setDigestAlgo(HashAlgorithm digestAlgo) { this.digestAlgo = digestAlgo; }
Returns:the opc package to be used by this thread, stored as thread-local
/** * @return the opc package to be used by this thread, stored as thread-local */
public OPCPackage getOpcPackage() { return opcPackage.get(); }
Params:
  • opcPackage – the opc package to be handled by this thread, stored as thread-local
/** * @param opcPackage the opc package to be handled by this thread, stored as thread-local */
public void setOpcPackage(OPCPackage opcPackage) { this.opcPackage.set(opcPackage); }
Returns:the private key
/** * @return the private key */
public PrivateKey getKey() { return key; }
Params:
  • key – the private key
/** * @param key the private key */
public void setKey(PrivateKey key) { this.key = key; }
Returns:the certificate chain, index 0 is usually the certificate matching the private key
/** * @return the certificate chain, index 0 is usually the certificate matching * the private key */
public List<X509Certificate> getSigningCertificateChain() { return signingCertificateChain; }
Params:
  • signingCertificateChain – the certificate chain, index 0 should be the certificate matching the private key
/** * @param signingCertificateChain the certificate chain, index 0 should be * the certificate matching the private key */
public void setSigningCertificateChain( List<X509Certificate> signingCertificateChain) { this.signingCertificateChain = signingCertificateChain; }
Returns:the time at which the document is signed, also used for the timestamp service. defaults to now
/** * @return the time at which the document is signed, also used for the timestamp service. * defaults to now */
public Date getExecutionTime() { return executionTime; }
Params:
  • executionTime – sets the time at which the document ought to be signed
/** * @param executionTime sets the time at which the document ought to be signed */
public void setExecutionTime(Date executionTime) { this.executionTime = executionTime; }
Returns:the formatted execution time (SIGNATURE_TIME_FORMAT)
Since:POI 4.0.0
/** * @return the formatted execution time ({@link #SIGNATURE_TIME_FORMAT}) * * @since POI 4.0.0 */
public String formatExecutionTime() { final DateFormat fmt = new SimpleDateFormat(SIGNATURE_TIME_FORMAT, Locale.ROOT); fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC); return fmt.format(getExecutionTime()); }
Sets the executionTime which is in standard format (SIGNATURE_TIME_FORMAT)
Params:
  • executionTime – the execution time
Since:POI 4.0.0
/** * Sets the executionTime which is in standard format ({@link #SIGNATURE_TIME_FORMAT}) * @param executionTime the execution time * * @since POI 4.0.0 */
public void setExecutionTime(String executionTime) { if (executionTime != null && !"".equals(executionTime)){ final DateFormat fmt = new SimpleDateFormat(SIGNATURE_TIME_FORMAT, Locale.ROOT); fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC); try { this.executionTime = fmt.parse(executionTime); } catch (ParseException e) { LOG.log(POILogger.WARN, "Illegal execution time: "+executionTime); } } }
Returns:the service to be used for XAdES-EPES properties. There's no default implementation
/** * @return the service to be used for XAdES-EPES properties. There's no default implementation */
public SignaturePolicyService getSignaturePolicyService() { return signaturePolicyService; }
Params:
  • signaturePolicyService – the service to be used for XAdES-EPES properties
/** * @param signaturePolicyService the service to be used for XAdES-EPES properties */
public void setSignaturePolicyService(SignaturePolicyService signaturePolicyService) { this.signaturePolicyService = signaturePolicyService; }
Returns:the dereferencer used for Reference/@URI attributes, defaults to OOXMLURIDereferencer
/** * @return the dereferencer used for Reference/@URI attributes, defaults to {@link OOXMLURIDereferencer} */
public URIDereferencer getUriDereferencer() { return uriDereferencer; }
Params:
  • uriDereferencer – the dereferencer used for Reference/@URI attributes
/** * @param uriDereferencer the dereferencer used for Reference/@URI attributes */
public void setUriDereferencer(URIDereferencer uriDereferencer) { this.uriDereferencer = uriDereferencer; }
Returns:Gives back the human-readable description of what the citizen will be signing. The default value is "Office OpenXML Document".
/** * @return Gives back the human-readable description of what the citizen * will be signing. The default value is "Office OpenXML Document". */
public String getSignatureDescription() { return signatureDescription; }
Params:
  • signatureDescription – the human-readable description of what the citizen will be signing.
/** * @param signatureDescription the human-readable description of * what the citizen will be signing. */
public void setSignatureDescription(String signatureDescription) { this.signatureDescription = signatureDescription; }
Returns:the default canonicalization method, defaults to INCLUSIVE
/** * @return the default canonicalization method, defaults to INCLUSIVE */
public String getCanonicalizationMethod() { return canonicalizationMethod; }
Params:
  • canonicalizationMethod – the default canonicalization method
/** * @param canonicalizationMethod the default canonicalization method */
public void setCanonicalizationMethod(String canonicalizationMethod) { this.canonicalizationMethod = verifyCanonicalizationMethod(canonicalizationMethod, CanonicalizationMethod.INCLUSIVE); } private static String verifyCanonicalizationMethod(String canonicalizationMethod, String defaultMethod) { if (canonicalizationMethod == null || canonicalizationMethod.isEmpty()) { return defaultMethod; } switch (canonicalizationMethod) { case CanonicalizationMethod.INCLUSIVE: case CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS: case CanonicalizationMethod.ENVELOPED: case CanonicalizationMethod.EXCLUSIVE: case CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS: return canonicalizationMethod; } throw new EncryptedDocumentException("Unknown CanonicalizationMethod: "+canonicalizationMethod); }
Returns:The signature Id attribute value used to create the XML signature. Defaults to "idPackageSignature"
/** * @return The signature Id attribute value used to create the XML signature. * Defaults to "idPackageSignature" */
public String getPackageSignatureId() { return packageSignatureId; }
Params:
  • packageSignatureId – The signature Id attribute value used to create the XML signature. A null value will trigger an automatically generated signature Id.
/** * @param packageSignatureId The signature Id attribute value used to create the XML signature. * A <code>null</code> value will trigger an automatically generated signature Id. */
public void setPackageSignatureId(String packageSignatureId) { this.packageSignatureId = nvl(packageSignatureId,"xmldsig-"+UUID.randomUUID()); }
Returns:the url of the timestamp provider (TSP)
/** * @return the url of the timestamp provider (TSP) */
public String getTspUrl() { return tspUrl; }
Params:
  • tspUrl – the url of the timestamp provider (TSP)
/** * @param tspUrl the url of the timestamp provider (TSP) */
public void setTspUrl(String tspUrl) { this.tspUrl = tspUrl; }
Returns:if true, uses timestamp-request/response mimetype, if false, timestamp-query/reply mimetype
/** * @return if true, uses timestamp-request/response mimetype, * if false, timestamp-query/reply mimetype */
public boolean isTspOldProtocol() { return tspOldProtocol; }
Params:
  • tspOldProtocol – defines the timestamp-protocol mimetype
See Also:
/** * @param tspOldProtocol defines the timestamp-protocol mimetype * @see #isTspOldProtocol */
public void setTspOldProtocol(boolean tspOldProtocol) { this.tspOldProtocol = tspOldProtocol; }
Returns:the hash algorithm to be used for the timestamp entry. Defaults to the hash algorithm of the main entry
/** * @return the hash algorithm to be used for the timestamp entry. * Defaults to the hash algorithm of the main entry */
public HashAlgorithm getTspDigestAlgo() { return nvl(tspDigestAlgo,digestAlgo); }
Params:
  • tspDigestAlgo – the algorithm to be used for the timestamp entry. if null, the hash algorithm of the main entry
/** * @param tspDigestAlgo the algorithm to be used for the timestamp entry. * if <code>null</code>, the hash algorithm of the main entry */
public void setTspDigestAlgo(HashAlgorithm tspDigestAlgo) { this.tspDigestAlgo = tspDigestAlgo; }
Returns:the proxy url to be used for all communications. Currently this affects the timestamp service
/** * @return the proxy url to be used for all communications. * Currently this affects the timestamp service */
public String getProxyUrl() { return proxyUrl; }
Params:
  • proxyUrl – the proxy url to be used for all communications. Currently this affects the timestamp service
/** * @param proxyUrl the proxy url to be used for all communications. * Currently this affects the timestamp service */
public void setProxyUrl(String proxyUrl) { this.proxyUrl = proxyUrl; }
Returns:the timestamp service. Defaults to TSPTimeStampService
/** * @return the timestamp service. Defaults to {@link TSPTimeStampService} */
public TimeStampService getTspService() { return tspService; }
Params:
  • tspService – the timestamp service
/** * @param tspService the timestamp service */
public void setTspService(TimeStampService tspService) { this.tspService = tspService; }
Returns:the user id for the timestamp service - currently only basic authorization is supported
/** * @return the user id for the timestamp service - currently only basic authorization is supported */
public String getTspUser() { return tspUser; }
Params:
  • tspUser – the user id for the timestamp service - currently only basic authorization is supported
/** * @param tspUser the user id for the timestamp service - currently only basic authorization is supported */
public void setTspUser(String tspUser) { this.tspUser = tspUser; }
Returns:the password for the timestamp service
/** * @return the password for the timestamp service */
public String getTspPass() { return tspPass; }
Params:
  • tspPass – the password for the timestamp service
/** * @param tspPass the password for the timestamp service */
public void setTspPass(String tspPass) { this.tspPass = tspPass; }
Returns:the validator for the timestamp service (certificate)
/** * @return the validator for the timestamp service (certificate) */
public TimeStampServiceValidator getTspValidator() { return tspValidator; }
Params:
  • tspValidator – the validator for the timestamp service (certificate)
/** * @param tspValidator the validator for the timestamp service (certificate) */
public void setTspValidator(TimeStampServiceValidator tspValidator) { this.tspValidator = tspValidator; }
Returns:the optional revocation data service used for XAdES-C and XAdES-X-L. When null the signature will be limited to XAdES-T only.
/** * @return the optional revocation data service used for XAdES-C and XAdES-X-L. * When <code>null</code> the signature will be limited to XAdES-T only. */
public RevocationDataService getRevocationDataService() { return revocationDataService; }
Params:
  • revocationDataService – the optional revocation data service used for XAdES-C and XAdES-X-L. When null the signature will be limited to XAdES-T only.
/** * @param revocationDataService the optional revocation data service used for XAdES-C and XAdES-X-L. * When <code>null</code> the signature will be limited to XAdES-T only. */
public void setRevocationDataService(RevocationDataService revocationDataService) { this.revocationDataService = revocationDataService; }
Returns:hash algorithm used for XAdES. Defaults to the getDigestAlgo()
/** * @return hash algorithm used for XAdES. Defaults to the {@link #getDigestAlgo()} */
public HashAlgorithm getXadesDigestAlgo() { return nvl(xadesDigestAlgo,digestAlgo); }
Params:
  • xadesDigestAlgo – hash algorithm used for XAdES. When null, defaults to getDigestAlgo()
/** * @param xadesDigestAlgo hash algorithm used for XAdES. * When <code>null</code>, defaults to {@link #getDigestAlgo()} */
public void setXadesDigestAlgo(HashAlgorithm xadesDigestAlgo) { this.xadesDigestAlgo = xadesDigestAlgo; }
Params:
  • xadesDigestAlgo – hash algorithm used for XAdES. When null, defaults to getDigestAlgo()
Since:POI 4.0.0
/** * @param xadesDigestAlgo hash algorithm used for XAdES. * When <code>null</code>, defaults to {@link #getDigestAlgo()} * * @since POI 4.0.0 */
public void setXadesDigestAlgo(String xadesDigestAlgo) { this.xadesDigestAlgo = getDigestMethodAlgo(xadesDigestAlgo); }
Returns:the user agent used for http communication (e.g. to the TSP)
/** * @return the user agent used for http communication (e.g. to the TSP) */
public String getUserAgent() { return userAgent; }
Params:
  • userAgent – the user agent used for http communication (e.g. to the TSP)
/** * @param userAgent the user agent used for http communication (e.g. to the TSP) */
public void setUserAgent(String userAgent) { this.userAgent = userAgent; }
Returns:the asn.1 object id for the tsp request policy. Defaults to 1.3.6.1.4.1.13762.3
/** * @return the asn.1 object id for the tsp request policy. * Defaults to <code>1.3.6.1.4.1.13762.3</code> */
public String getTspRequestPolicy() { return tspRequestPolicy; }
Params:
  • tspRequestPolicy – the asn.1 object id for the tsp request policy.
/** * @param tspRequestPolicy the asn.1 object id for the tsp request policy. */
public void setTspRequestPolicy(String tspRequestPolicy) { this.tspRequestPolicy = tspRequestPolicy; }
Returns:true, if the whole certificate chain is included in the signature. When false, only the signer cert will be included
/** * @return true, if the whole certificate chain is included in the signature. * When false, only the signer cert will be included */
public boolean isIncludeEntireCertificateChain() { return includeEntireCertificateChain; }
Params:
  • includeEntireCertificateChain – if true, include the whole certificate chain. If false, only include the signer cert
/** * @param includeEntireCertificateChain if true, include the whole certificate chain. * If false, only include the signer cert */
public void setIncludeEntireCertificateChain(boolean includeEntireCertificateChain) { this.includeEntireCertificateChain = includeEntireCertificateChain; }
Returns:if true, issuer serial number is included
/** * @return if true, issuer serial number is included */
public boolean isIncludeIssuerSerial() { return includeIssuerSerial; }
Params:
  • includeIssuerSerial – if true, issuer serial number is included
/** * @param includeIssuerSerial if true, issuer serial number is included */
public void setIncludeIssuerSerial(boolean includeIssuerSerial) { this.includeIssuerSerial = includeIssuerSerial; }
Returns:if true, the key value of the public key (certificate) is included
/** * @return if true, the key value of the public key (certificate) is included */
public boolean isIncludeKeyValue() { return includeKeyValue; }
Params:
  • includeKeyValue – if true, the key value of the public key (certificate) is included
/** * @param includeKeyValue if true, the key value of the public key (certificate) is included */
public void setIncludeKeyValue(boolean includeKeyValue) { this.includeKeyValue = includeKeyValue; }
Returns:the xades role element. If null the claimed role element is omitted. Defaults to null
/** * @return the xades role element. If <code>null</code> the claimed role element is omitted. * Defaults to <code>null</code> */
public String getXadesRole() { return xadesRole; }
Params:
  • xadesRole – the xades role element. If null the claimed role element is omitted.
/** * @param xadesRole the xades role element. If <code>null</code> the claimed role element is omitted. */
public void setXadesRole(String xadesRole) { this.xadesRole = xadesRole; }
Returns:the Id for the XAdES SignedProperties element. Defaults to idSignedProperties
/** * @return the Id for the XAdES SignedProperties element. * Defaults to <code>idSignedProperties</code> */
public String getXadesSignatureId() { return nvl(xadesSignatureId, "idSignedProperties"); }
Params:
  • xadesSignatureId – the Id for the XAdES SignedProperties element. When null defaults to idSignedProperties
/** * @param xadesSignatureId the Id for the XAdES SignedProperties element. * When <code>null</code> defaults to <code>idSignedProperties</code> */
public void setXadesSignatureId(String xadesSignatureId) { this.xadesSignatureId = xadesSignatureId; }
Returns:when true, include the policy-implied block. Defaults to true
/** * @return when true, include the policy-implied block. * Defaults to <code>true</code> */
public boolean isXadesSignaturePolicyImplied() { return xadesSignaturePolicyImplied; }
Params:
  • xadesSignaturePolicyImplied – when true, include the policy-implied block
/** * @param xadesSignaturePolicyImplied when true, include the policy-implied block */
public void setXadesSignaturePolicyImplied(boolean xadesSignaturePolicyImplied) { this.xadesSignaturePolicyImplied = xadesSignaturePolicyImplied; }
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.
Returns:when true, the issuer DN is used instead of the issuer X500 principal
/** * 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. * * @return when true, the issuer DN is used instead of the issuer X500 principal */
public boolean isXadesIssuerNameNoReverseOrder() { return xadesIssuerNameNoReverseOrder; }
Params:
  • xadesIssuerNameNoReverseOrder – when true, the issuer DN instead of the issuer X500 prinicpal is used
/** * @param xadesIssuerNameNoReverseOrder when true, the issuer DN instead of the issuer X500 prinicpal is used */
public void setXadesIssuerNameNoReverseOrder(boolean xadesIssuerNameNoReverseOrder) { this.xadesIssuerNameNoReverseOrder = xadesIssuerNameNoReverseOrder; }
Returns:the event listener which is active while xml structure for the signature is created. Defaults to SignatureMarshalListener
/** * @return the event listener which is active while xml structure for * the signature is created. * Defaults to {@link SignatureMarshalListener} */
public EventListener getSignatureMarshalListener() { return signatureMarshalListener; }
Params:
  • signatureMarshalListener – the event listener watching the xml structure generation for the signature
/** * @param signatureMarshalListener the event listener watching the xml structure * generation for the signature */
public void setSignatureMarshalListener(EventListener signatureMarshalListener) { this.signatureMarshalListener = signatureMarshalListener; }
Returns:the map of namespace uri (key) to prefix (value)
/** * @return the map of namespace uri (key) to prefix (value) */
public Map<String, String> getNamespacePrefixes() { return namespacePrefixes; }
Params:
  • namespacePrefixes – the map of namespace uri (key) to prefix (value)
/** * @param namespacePrefixes the map of namespace uri (key) to prefix (value) */
public void setNamespacePrefixes(Map<String, String> namespacePrefixes) { this.namespacePrefixes.clear(); this.namespacePrefixes.putAll(namespacePrefixes); }
helper method for null/default value handling
Params:
  • value – the value to be tested
  • defaultValue – the default value
Returns:if value is not null, return value otherwise defaultValue
/** * helper method for null/default value handling * @param value the value to be tested * @param defaultValue the default value * @return if value is not null, return value otherwise defaultValue */
private static <T> T nvl(T value, T defaultValue) { return value == null ? defaultValue : value; }
Returns:the uri for the signature method, i.e. currently only rsa is supported, so it's the rsa variant of the main digest
/** * @return the uri for the signature method, i.e. currently only rsa is * supported, so it's the rsa variant of the main digest */
public String getSignatureMethodUri() { switch (getDigestAlgo()) { case sha1: return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1; case sha224: return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA224; case sha256: return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256; case sha384: return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384; case sha512: return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512; case ripemd160: return XMLSignature.ALGO_ID_SIGNATURE_RSA_RIPEMD160; default: throw new EncryptedDocumentException("Hash algorithm " +getDigestAlgo()+" not supported for signing."); } }
Returns:the uri for the main digest
/** * @return the uri for the main digest */
public String getDigestMethodUri() { return getDigestMethodUri(getDigestAlgo()); }
Converts the digest algorithm - currently only sha* and ripemd160 is supported. MS Office only supports sha1, sha256, sha384, sha512.
Params:
  • digestAlgo – the digest algorithm
Returns:the uri for the given digest
/** * Converts the digest algorithm - currently only sha* and ripemd160 is supported. * MS Office only supports sha1, sha256, sha384, sha512. * * @param digestAlgo the digest algorithm * @return the uri for the given digest */
public static String getDigestMethodUri(HashAlgorithm digestAlgo) { switch (digestAlgo) { case sha1: return DigestMethod.SHA1; case sha224: return DigestMethod_SHA224; case sha256: return DigestMethod.SHA256; case sha384: return DigestMethod_SHA384; case sha512: return DigestMethod.SHA512; case ripemd160: return DigestMethod.RIPEMD160; default: throw new EncryptedDocumentException("Hash algorithm " +digestAlgo+" not supported for signing."); } }
Converts the digest algorithm ur - currently only sha* and ripemd160 is supported. MS Office only supports sha1, sha256, sha384, sha512.
Params:
  • digestMethodUri – the digest algorithm uri
Returns:the hash algorithm for the given digest
/** * Converts the digest algorithm ur - currently only sha* and ripemd160 is supported. * MS Office only supports sha1, sha256, sha384, sha512. * * @param digestMethodUri the digest algorithm uri * @return the hash algorithm for the given digest */
private static HashAlgorithm getDigestMethodAlgo(String digestMethodUri) { if (digestMethodUri == null || digestMethodUri.isEmpty()) { return null; } switch (digestMethodUri) { case DigestMethod.SHA1: return HashAlgorithm.sha1; case DigestMethod_SHA224: return HashAlgorithm.sha224; case DigestMethod.SHA256: return HashAlgorithm.sha256; case DigestMethod_SHA384: return HashAlgorithm.sha384; case DigestMethod.SHA512: return HashAlgorithm.sha512; case DigestMethod.RIPEMD160: return HashAlgorithm.ripemd160; default: throw new EncryptedDocumentException("Hash algorithm " +digestMethodUri+" not supported for signing."); } }
Set the digest algorithm based on the method uri. This is used when a signature was successful validated and the signature configuration is updated
Params:
  • signatureMethodUri – the method uri
Since:POI 4.0.0
/** * Set the digest algorithm based on the method uri. * This is used when a signature was successful validated and the signature * configuration is updated * * @param signatureMethodUri the method uri * * @since POI 4.0.0 */
public void setSignatureMethodFromUri(final String signatureMethodUri) { switch (signatureMethodUri) { case XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1: setDigestAlgo(HashAlgorithm.sha1); break; case XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA224: setDigestAlgo(HashAlgorithm.sha224); break; case XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256: setDigestAlgo(HashAlgorithm.sha256); break; case XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384: setDigestAlgo(HashAlgorithm.sha384); break; case XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512: setDigestAlgo(HashAlgorithm.sha512); break; case XMLSignature.ALGO_ID_SIGNATURE_RSA_RIPEMD160: setDigestAlgo(HashAlgorithm.ripemd160); break; default: throw new EncryptedDocumentException("Hash algorithm " +signatureMethodUri+" not supported."); } }
Params:
  • signatureFactory – the xml signature factory, saved as thread-local
/** * @param signatureFactory the xml signature factory, saved as thread-local */
public void setSignatureFactory(XMLSignatureFactory signatureFactory) { this.signatureFactory.set(signatureFactory); }
Returns:the xml signature factory (thread-local)
/** * @return the xml signature factory (thread-local) */
public XMLSignatureFactory getSignatureFactory() { XMLSignatureFactory sigFac = signatureFactory.get(); if (sigFac == null) { sigFac = XMLSignatureFactory.getInstance("DOM", getProvider()); setSignatureFactory(sigFac); } return sigFac; }
Params:
  • keyInfoFactory – the key factory, saved as thread-local
/** * @param keyInfoFactory the key factory, saved as thread-local */
public void setKeyInfoFactory(KeyInfoFactory keyInfoFactory) { this.keyInfoFactory.set(keyInfoFactory); }
Returns:the key factory (thread-local)
/** * @return the key factory (thread-local) */
public KeyInfoFactory getKeyInfoFactory() { KeyInfoFactory keyFac = keyInfoFactory.get(); if (keyFac == null) { keyFac = KeyInfoFactory.getInstance("DOM", getProvider()); setKeyInfoFactory(keyFac); } return keyFac; }
This method tests the existence of xml signature provider in the following order:
  • the class pointed to by the system property "jsr105Provider"
  • the Santuario xmlsec provider
  • the JDK xmlsec provider
For signing the classes are linked against the Santuario xmlsec, so this might only work for validation (not tested).
Returns:the xml dsig provider
/** * 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 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; }
See Also:
Returns:the cannonicalization method for XAdES-XL signing. Defaults to EXCLUSIVE
/** * @return the cannonicalization method for XAdES-XL signing. * Defaults to <code>EXCLUSIVE</code> * @see <a href="http://docs.oracle.com/javase/7/docs/api/javax/xml/crypto/dsig/CanonicalizationMethod.html">javax.xml.crypto.dsig.CanonicalizationMethod</a> */
public String getXadesCanonicalizationMethod() { return xadesCanonicalizationMethod; }
Params:
  • xadesCanonicalizationMethod – the cannonicalization method for XAdES-XL signing
See Also:
/** * @param xadesCanonicalizationMethod the cannonicalization method for XAdES-XL signing * @see <a href="http://docs.oracle.com/javase/7/docs/api/javax/xml/crypto/dsig/CanonicalizationMethod.html">javax.xml.crypto.dsig.CanonicalizationMethod</a> */
public void setXadesCanonicalizationMethod(String xadesCanonicalizationMethod) { this.xadesCanonicalizationMethod = verifyCanonicalizationMethod(xadesCanonicalizationMethod, CanonicalizationMethod.EXCLUSIVE); }
Returns:true, if the signature config is to be updated based on the successful validated document
Since:POI 4.0.0
/** * @return true, if the signature config is to be updated based on the successful validated document * * @since POI 4.0.0 */
public boolean isUpdateConfigOnValidate() { return updateConfigOnValidate; }
The signature config can be updated if a document is succesful validated. This flag is used for activating this modifications. Defaults to false

Params:
  • updateConfigOnValidate – if true, update config on validate
Since:POI 4.0.0
/** * The signature config can be updated if a document is succesful validated. * This flag is used for activating this modifications. * Defaults to {@code false}<p> * * @param updateConfigOnValidate if true, update config on validate * * @since POI 4.0.0 */
public void setUpdateConfigOnValidate(boolean updateConfigOnValidate) { this.updateConfigOnValidate = updateConfigOnValidate; }
Returns:true, if multiple signatures can be attached
Since:POI 4.1.0
/** * @return true, if multiple signatures can be attached * * @since POI 4.1.0 */
public boolean isAllowMultipleSignatures() { return allowMultipleSignatures; }
Activate multiple signatures
Params:
  • allowMultipleSignatures – if true, the signature will be added, otherwise all existing signatures will be replaced by the current
Since:POI 4.1.0
/** * Activate multiple signatures * * @param allowMultipleSignatures if true, the signature will be added, * otherwise all existing signatures will be replaced by the current * * @since POI 4.1.0 */
public void setAllowMultipleSignatures(boolean allowMultipleSignatures) { this.allowMultipleSignatures = allowMultipleSignatures; } }