/* ====================================================================
   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.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import javax.xml.crypto.URIDereferencer;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.hpsf.ClassID;
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.Internal;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.Removal;
import org.apache.xml.security.signature.XMLSignature;

/**
 * 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 Logger LOG = LogManager.getLogger(SignatureConfig.class);
    private static final String DigestMethod_SHA224 = "http://www.w3.org/2001/04/xmldsig-more#sha224";
    private static final String DigestMethod_SHA384 = "http://www.w3.org/2001/04/xmldsig-more#sha384";
    private static final String XMLSEC_SANTUARIO = "org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI";
    private static final String XMLSEC_JDK = "org.jcp.xml.dsig.internal.dom.XMLDSigRI";

    private static final List<Supplier<SignatureFacet>> DEFAULT_FACETS = Arrays.asList(
        OOXMLSignatureFacet::new,
        KeyInfoSignatureFacet::new,
        XAdESSignatureFacet::new,
        Office2010SignatureFacet::new
    );


    private final ThreadLocal<OPCPackage> opcPackage = new ThreadLocal<>();
    private final ThreadLocal<XMLSignatureFactory> signatureFactory = new ThreadLocal<>();
    private final ThreadLocal<KeyInfoFactory> keyInfoFactory = new ThreadLocal<>();
    private final 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.
     */
    private SignaturePolicyService signaturePolicyService;
    private URIDereferencer uriDereferencer = new OOXMLURIDereferencer();
    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.
     */
    private TimeStampService tspService = new TSPTimeStampService();
    /**
     * timestamp service provider URL
     */
    private String tspUrl;
    private boolean tspOldProtocol;
    /**
     * 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.
     */
    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 <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
     */
    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.
     */
    private boolean xadesIssuerNameNoReverseOrder = true;

    /**
     * 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".
     */
    private String signatureDescription = "Office OpenXML Document";

    /**
     * Only applies when working with visual signatures:
     * Specifies a GUID which can be cross-referenced with the GUID of the signature line stored in the document content.
     * I.e. the signatureline element id attribute in the document/sheet has to be references in the SetupId element.
     */
    private ClassID signatureImageSetupId;

    /**
     * Provides a signature image for visual signature lines
     */
    private byte[] signatureImage;
    /**
     * The image shown, when the signature is valid
     */
    private byte[] signatureImageValid;
    /**
     * The image shown, when the signature is invalid
     */
    private byte[] signatureImageInvalid;

    /**
     * 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 SignatureMarshalListener signatureMarshalListener = new SignatureMarshalDefaultListener();

    /**
     * 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
     */
    private boolean updateConfigOnValidate = false;

    /**
     * if true, the signature is added to the existing signatures
     *
     * @since POI 4.1.0
     */
    private boolean allowMultipleSignatures = false;

    public SignatureConfig() {
        // OOo doesn't like ds namespaces so per default prefixing is off.
        // namespacePrefixes.put(XML_DIGSIG_NS, "");
        namespacePrefixes.put(OO_DIGSIG_NS, "mdssi");
        namespacePrefixes.put(XADES_132_NS, "xd");
    }

    /**
     * @param signatureFacet the signature facet is appended to facet list
     */
    public void addSignatureFacet(SignatureFacet signatureFacet) {
        signatureFacets.add(signatureFacet);
    }

    /**
     * @return the list of facets, may be empty when the config object is not initialized
     */
    public List<SignatureFacet> getSignatureFacets() {
        if (signatureFacets.isEmpty()) {
            return DEFAULT_FACETS.stream().map(Supplier::get).collect(Collectors.toList());
        } else {
            return signatureFacets;
        }
    }

    /**
     * @param signatureFacets the new list of facets
     */
    public void setSignatureFacets(List<SignatureFacet> signatureFacets) {
        this.signatureFacets = signatureFacets;
    }

    /**
     * @return the main digest algorithm, defaults to sha256
     */
    public HashAlgorithm getDigestAlgo() {
        return digestAlgo;
    }

    /**
     * @param digestAlgo the main digest algorithm
     */
    public void setDigestAlgo(HashAlgorithm digestAlgo) {
        this.digestAlgo = digestAlgo;
    }

    /**
     * @return the opc package to be used by this thread, stored as thread-local
     *
     * @deprecated in POI 5.0.0 - use {@link SignatureInfo#setOpcPackage(OPCPackage)} instead
     */
    @Deprecated
    @Removal(version = "5.0.0")
    public OPCPackage getOpcPackage() {
        return opcPackage.get();
    }

    /**
     * @param opcPackage the opc package to be handled by this thread, stored as thread-local
     *
     * @deprecated in POI 5.0.0 - use {@link SignatureInfo#setOpcPackage(OPCPackage)} instead
     */
    @Deprecated
    @Removal(version = "5.0.0")
    public void setOpcPackage(OPCPackage opcPackage) {
        this.opcPackage.set(opcPackage);
    }

    /**
     * @return the private key
     */
    public PrivateKey getKey() {
        return key;
    }

    /**
     * @param key the private key
     */
    public void setKey(PrivateKey key) {
        this.key = key;
    }

    /**
     * @return the certificate chain, index 0 is usually the certificate matching
     * the private key
     */
    public List<X509Certificate> getSigningCertificateChain() {
        return signingCertificateChain;
    }

    /**
     * @param signingCertificateChain the certificate chain, index 0 should be
     * the certificate matching the private key
     */
    public void setSigningCertificateChain(
            List<X509Certificate> signingCertificateChain) {
        this.signingCertificateChain = signingCertificateChain;
    }

    /**
     * @return the time at which the document is signed, also used for the timestamp service.
     * defaults to now
     */
    public Date getExecutionTime() {
        return executionTime;
    }

    /**
     * @param executionTime sets the time at which the document ought to be signed
     */
    public void setExecutionTime(Date executionTime) {
        this.executionTime = executionTime;
    }

    /**
     * @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 ({@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.atWarn().log("Illegal execution time: {}. Must be formatted as " + SIGNATURE_TIME_FORMAT, executionTime);
            }
        }
    }

    /**
     * @return the service to be used for XAdES-EPES properties. There's no default implementation
     */
    public SignaturePolicyService getSignaturePolicyService() {
        return signaturePolicyService;
    }

    /**
     * @param signaturePolicyService the service to be used for XAdES-EPES properties
     */
    public void setSignaturePolicyService(SignaturePolicyService signaturePolicyService) {
        this.signaturePolicyService = signaturePolicyService;
    }

    /**
     * @return the dereferencer used for Reference/@URI attributes, defaults to {@link OOXMLURIDereferencer}
     *
     * @deprecated in POI 5.0.0 - use {@link SignatureInfo#getUriDereferencer()} instead
     */
    @Deprecated
    @Removal(version = "5.0.0")
    public URIDereferencer getUriDereferencer() {
        return uriDereferencer;
    }

    /**
     * @param uriDereferencer the dereferencer used for Reference/@URI attributes
     *
     * @deprecated in POI 5.0.0 - use {@link SignatureInfo#setUriDereferencer(URIDereferencer)} instead
     */
    @Deprecated
    @Removal(version = "5.0.0")
    public void setUriDereferencer(URIDereferencer uriDereferencer) {
        this.uriDereferencer = uriDereferencer;
    }

    /**
     * @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;
    }

    /**
     * @param signatureDescription the human-readable description of
     * what the citizen will be signing.
     */
    public void setSignatureDescription(String signatureDescription) {
        this.signatureDescription = signatureDescription;
    }

    public byte[] getSignatureImage() {
        return signatureImage;
    }

    public byte[] getSignatureImageValid() {
        return signatureImageValid;
    }

    public byte[] getSignatureImageInvalid() {
        return signatureImageInvalid;
    }

    public ClassID getSignatureImageSetupId() {
        return signatureImageSetupId;
    }

    public void setSignatureImageSetupId(ClassID signatureImageSetupId) {
        this.signatureImageSetupId = signatureImageSetupId;
    }

    public void setSignatureImage(byte[] signatureImage) {
        this.signatureImage = (signatureImage == null) ? null : signatureImage.clone();
    }

    public void setSignatureImageValid(byte[] signatureImageValid) {
        this.signatureImageValid = (signatureImageValid == null) ? null : signatureImageValid.clone();
    }

    public void setSignatureImageInvalid(byte[] signatureImageInvalid) {
        this.signatureImageInvalid = (signatureImageInvalid == null) ? null : signatureImageInvalid.clone();
    }

    /**
     * @return the default canonicalization method, defaults to INCLUSIVE
     */
    public String getCanonicalizationMethod() {
        return canonicalizationMethod;
    }

    /**
     * @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 Transform.ENVELOPED:
            case CanonicalizationMethod.INCLUSIVE:
            case CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS:
            case CanonicalizationMethod.EXCLUSIVE:
            case CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS:
                return canonicalizationMethod;
        }

        throw new EncryptedDocumentException("Unknown CanonicalizationMethod: "+canonicalizationMethod);
    }

    /**
     * @return The signature Id attribute value used to create the XML signature.
     * Defaults to "idPackageSignature"
     */
    public String getPackageSignatureId() {
        return packageSignatureId;
    }

    /**
     * @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());
    }

    /**
     * @return the url of the timestamp provider (TSP)
     */
    public String getTspUrl() {
        return tspUrl;
    }

    /**
     * @param tspUrl the url of the timestamp provider (TSP)
     */
    public void setTspUrl(String tspUrl) {
        this.tspUrl = tspUrl;
    }

    /**
     * @return if true, uses timestamp-request/response mimetype,
     * if false, timestamp-query/reply mimetype
     */
    public boolean isTspOldProtocol() {
        return tspOldProtocol;
    }

    /**
     * @param tspOldProtocol defines the timestamp-protocol mimetype
     * @see #isTspOldProtocol
     */
    public void setTspOldProtocol(boolean tspOldProtocol) {
        this.tspOldProtocol = tspOldProtocol;
    }

    /**
     * @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);
    }

    /**
     * @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;
    }

    /**
     * @return the proxy url to be used for all communications.
     * Currently this affects the timestamp service
     */
    public String getProxyUrl() {
        return proxyUrl;
    }

    /**
     * @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;
    }

    /**
     * @return the timestamp service. Defaults to {@link TSPTimeStampService}
     */
    public TimeStampService getTspService() {
        return tspService;
    }

    /**
     * @param tspService the timestamp service
     */
    public void setTspService(TimeStampService tspService) {
        this.tspService = tspService;
    }

    /**
     * @return the user id for the timestamp service - currently only basic authorization is supported
     */
    public String getTspUser() {
        return tspUser;
    }

    /**
     * @param tspUser the user id for the timestamp service - currently only basic authorization is supported
     */
    public void setTspUser(String tspUser) {
        this.tspUser = tspUser;
    }

    /**
     * @return the password for the timestamp service
     */
    public String getTspPass() {
        return tspPass;
    }

    /**
     * @param tspPass the password for the timestamp service
     */
    public void setTspPass(String tspPass) {
        this.tspPass = tspPass;
    }

    /**
     * @return the validator for the timestamp service (certificate)
     */
    public TimeStampServiceValidator getTspValidator() {
        return tspValidator;
    }

    /**
     * @param tspValidator the validator for the timestamp service (certificate)
     */
    public void setTspValidator(TimeStampServiceValidator tspValidator) {
        this.tspValidator = tspValidator;
    }

    /**
     * @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;
    }

    /**
     * @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;
    }

    /**
     * @return hash algorithm used for XAdES. Defaults to the {@link #getDigestAlgo()}
     */
    public HashAlgorithm getXadesDigestAlgo() {
        return nvl(xadesDigestAlgo,digestAlgo);
    }

    /**
     * @param xadesDigestAlgo hash algorithm used for XAdES.
     * When <code>null</code>, defaults to {@link #getDigestAlgo()}
     */
    public void setXadesDigestAlgo(HashAlgorithm xadesDigestAlgo) {
        this.xadesDigestAlgo = xadesDigestAlgo;
    }

    /**
     * @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);
    }

    /**
     * @return the user agent used for http communication (e.g. to the TSP)
     */
    public String getUserAgent() {
        return userAgent;
    }

    /**
     * @param userAgent the user agent used for http communication (e.g. to the TSP)
     */
    public void setUserAgent(String userAgent) {
        this.userAgent = userAgent;
    }

    /**
     * @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;
    }

    /**
     * @param tspRequestPolicy the asn.1 object id for the tsp request policy.
     */
    public void setTspRequestPolicy(String tspRequestPolicy) {
        this.tspRequestPolicy = tspRequestPolicy;
    }

    /**
     * @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;
    }

    /**
     * @param includeEntireCertificateChain if true, include the whole certificate chain.
     * If false, only include the signer cert
     */
    public void setIncludeEntireCertificateChain(boolean includeEntireCertificateChain) {
        this.includeEntireCertificateChain = includeEntireCertificateChain;
    }

    /**
     * @return if true, issuer serial number is included
     */
    public boolean isIncludeIssuerSerial() {
        return includeIssuerSerial;
    }

    /**
     * @param includeIssuerSerial if true, issuer serial number is included
     */
    public void setIncludeIssuerSerial(boolean includeIssuerSerial) {
        this.includeIssuerSerial = includeIssuerSerial;
    }

    /**
     * @return if true, the key value of the public key (certificate) is included
     */
    public boolean isIncludeKeyValue() {
        return includeKeyValue;
    }

    /**
     * @param includeKeyValue if true, the key value of the public key (certificate) is included
     */
    public void setIncludeKeyValue(boolean includeKeyValue) {
        this.includeKeyValue = includeKeyValue;
    }

    /**
     * @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;
    }

    /**
     * @param xadesRole the xades role element. If <code>null</code> the claimed role element is omitted.
     */
    public void setXadesRole(String xadesRole) {
        this.xadesRole = xadesRole;
    }

    /**
     * @return the Id for the XAdES SignedProperties element.
     * Defaults to <code>idSignedProperties</code>
     */
    public String getXadesSignatureId() {
        return nvl(xadesSignatureId, "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;
    }

    /**
     * @return when true, include the policy-implied block.
     * Defaults to <code>true</code>
     */
    public boolean isXadesSignaturePolicyImplied() {
        return xadesSignaturePolicyImplied;
    }

    /**
     * @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.
     *
     * @return when true, the issuer DN is used instead of the issuer X500 principal
     */
    public boolean isXadesIssuerNameNoReverseOrder() {
        return xadesIssuerNameNoReverseOrder;
    }

    /**
     * @param xadesIssuerNameNoReverseOrder when true, the issuer DN instead of the issuer X500 prinicpal is used
     */
    public void setXadesIssuerNameNoReverseOrder(boolean xadesIssuerNameNoReverseOrder) {
        this.xadesIssuerNameNoReverseOrder = xadesIssuerNameNoReverseOrder;
    }


    /**
     * @return the event listener which is active while xml structure for the signature is created.
     * Defaults to {@link SignatureMarshalListener}
     */
    public SignatureMarshalListener getSignatureMarshalListener() {
        return signatureMarshalListener;
    }

    /**
     * @param signatureMarshalListener the event listener watching the xml structure
     * generation for the signature
     */
    public void setSignatureMarshalListener(SignatureMarshalListener signatureMarshalListener) {
        this.signatureMarshalListener = signatureMarshalListener;
    }

    /**
     * @return the map of namespace uri (key) to prefix (value)
     */
    public Map<String, String> getNamespacePrefixes() {
        return namespacePrefixes;
    }

    /**
     * @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
     * @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;
    }

    /**
     * @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.");
        }
    }

    /**
     * @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.
     *
     * @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.
     *
     * @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
     *
     * @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.");
        }
    }


    /**
     * @param signatureFactory the xml signature factory, saved as thread-local
     *
     * @deprecated in POI 5.0.0 - use {@link SignatureInfo#setSignatureFactory(XMLSignatureFactory)}
     */
    @Deprecated
    @Removal(version = "5.0.0")
    public void setSignatureFactory(XMLSignatureFactory signatureFactory) {
        this.signatureFactory.set(signatureFactory);
    }

    /**
     * @return the xml signature factory (thread-local)
     *
     * @deprecated in POI 5.0.0 - will be handled by SignatureInfo internally
     */
    @Deprecated
    @Removal(version = "5.0.0")
    public XMLSignatureFactory getSignatureFactory() {
        return signatureFactory.get();
    }

    /**
     * @param keyInfoFactory the key factory, saved as thread-local
     *
     * @deprecated in POI 5.0.0 - use {@link SignatureInfo#setKeyInfoFactory(KeyInfoFactory)}
     */
    @Deprecated
    @Removal(version = "5.0.0")
    public void setKeyInfoFactory(KeyInfoFactory keyInfoFactory) {
        this.keyInfoFactory.set(keyInfoFactory);
    }

    /**
     * @return the key factory (thread-local)
     *
     * @deprecated in POI 5.0.0 - will be handled by SignatureInfo internally
     */
    @Deprecated
    @Removal(version = "5.0.0")
    public KeyInfoFactory getKeyInfoFactory() {
        return keyInfoFactory.get();
    }

    /**
     * Helper method to set provider
     * @param provider the provider
     * @deprecated in POI 5.0.0 - use {@link SignatureInfo#setProvider(Provider)}
     */
    @Internal
    @Deprecated
    @Removal(version = "5.0.0")
    public void setProvider(Provider provider) {
        this.provider.set(provider);
    }

    /**
     * @return the cached provider or null if not set before
     *
     * @deprecated in POI 5.0.0 - will be handled by SignatureInfo internally
     */
    @Deprecated
    @Removal(version = "5.0.0")
    public Provider getProvider() {
        return provider.get();
    }

    /**
     * Determine the possible classes for XMLSEC.
     * The order is
     * <ol>
     * <li>the class pointed to by the system property "jsr105Provider"</li>
     * <li>the Santuario xmlsec provider</li>
     * <li>the JDK xmlsec provider</li>
     * </ol>
     *
     * @return a list of possible XMLSEC provider class names
     */
    public static String[] getProviderNames() {
        // need to check every time, as the system property might have been changed in the meantime
        String sysProp = System.getProperty("jsr105Provider");
        return (sysProp == null || "".equals(sysProp))
            ? new String[]{XMLSEC_SANTUARIO, XMLSEC_JDK}
            : new String[]{sysProp, XMLSEC_SANTUARIO, XMLSEC_JDK};
    }


    /**
     * @return the cannonicalization method for XAdES-XL signing.
     * Defaults to <code>EXCLUSIVE</code>
     * @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;
    }

    /**
     * @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);
    }

    /**
     * @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 {@code false}<p>
     *
     * @param updateConfigOnValidate if true, update config on validate
     *
     * @since POI 4.0.0
     */
    public void setUpdateConfigOnValidate(boolean updateConfigOnValidate) {
        this.updateConfigOnValidate = updateConfigOnValidate;
    }

    /**
     * @return true, if multiple signatures can be attached
     *
     * @since POI 4.1.0
     */
    public boolean isAllowMultipleSignatures() {
        return allowMultipleSignatures;
    }

    /**
     * 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;
    }
}