/**
 * 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.wss4j.dom.message;

import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dom.DOMStructure;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.XMLSignContext;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.keyinfo.KeyValue;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.ExcC14NParameterSpec;

import org.apache.wss4j.common.WSEncryptionPart;
import org.apache.wss4j.common.WSS4JConstants;
import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.crypto.CryptoType;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.token.BinarySecurity;
import org.apache.wss4j.common.token.DOMX509Data;
import org.apache.wss4j.common.token.DOMX509IssuerSerial;
import org.apache.wss4j.common.token.PKIPathSecurity;
import org.apache.wss4j.common.token.Reference;
import org.apache.wss4j.common.token.SecurityTokenReference;
import org.apache.wss4j.common.token.X509Security;
import org.apache.wss4j.common.util.KeyUtils;
import org.apache.wss4j.common.util.XMLUtils;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.WSDocInfo;
import org.apache.wss4j.dom.message.token.KerberosSecurity;
import org.apache.wss4j.dom.transform.STRTransform;
import org.apache.wss4j.dom.util.WSSecurityUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;


/**
 * Creates a Signature according to WS Specification, X509 profile.
 *
 * This class is a re-factored implementation of the previous WSS4J class
 * <code>WSSignEnvelope</code>. This new class allows better control of
 * the process to create a Signature and to add it to the Security header.
 *
 * The flexibility and fine granular control is required to implement a handler
 * that uses WSSecurityPolicy files to control the setup of a Security header.
 */
public class WSSecSignature extends WSSecSignatureBase {

    private static final org.slf4j.Logger LOG =
        org.slf4j.LoggerFactory.getLogger(WSSecSignature.class);

    protected XMLSignatureFactory signatureFactory;
    protected KeyInfo keyInfo;
    protected CanonicalizationMethod c14nMethod;
    protected XMLSignature sig;
    protected byte[] secretKey;
    protected String strUri;
    protected Element bstToken;
    protected String keyInfoUri;
    protected String certUri;
    protected byte[] signatureValue;

    private boolean useSingleCert = true;
    private String sigAlgo;
    private String canonAlgo = WSConstants.C14N_EXCL_OMIT_COMMENTS;
    private SecurityTokenReference secRef;
    private String customTokenValueType;
    private String customTokenId;
    private String encrKeySha1value;
    private Crypto crypto;
    private String digestAlgo = WSConstants.SHA1;
    private X509Certificate useThisCert;
    private boolean useCustomSecRef;
    private boolean bstAddedToSecurityHeader;
    private boolean includeSignatureToken;
    private boolean addInclusivePrefixes = true;
    private Element customKeyInfoElement;
    private Provider signatureProvider;

    public WSSecSignature(WSSecHeader securityHeader) {
        super(securityHeader);
        init(null);
    }

    public WSSecSignature(Document doc) {
        this(doc, null);
    }

    public WSSecSignature(Document doc, Provider provider) {
        super(doc);
        init(provider);
    }

    private void init(Provider provider) {
        if (provider == null) {
            // Try to install the Santuario Provider - fall back to the JDK provider if this does
            // not work
            try {
                signatureFactory = XMLSignatureFactory.getInstance("DOM", "ApacheXMLDSig");
            } catch (NoSuchProviderException ex) {
                signatureFactory = XMLSignatureFactory.getInstance("DOM");
            }
        } else {
            signatureFactory = XMLSignatureFactory.getInstance("DOM", provider);
        }
    }

    /**
     * Initialize a WSSec Signature.
     *
     * The method sets up and initializes a WSSec Signature structure after the
     * relevant information was set. After setup of the references to elements
     * to sign may be added. After all references are added they can be signed.
     *
     * This method does not add the Signature element to the security header.
     * See <code>prependSignatureElementToHeader()</code> method.
     *
     * @param cr An instance of the Crypto API to handle keystore and certificates
     * @throws WSSecurityException
     */
    public void prepare(Crypto cr)
        throws WSSecurityException {
        //
        // Gather some info about the document to process and store it for
        // retrieval
        //
        crypto = cr;
        WSDocInfo wsDocInfo = getWsDocInfo();
        if (wsDocInfo == null) {
            wsDocInfo = new WSDocInfo(getDocument());
            super.setWsDocInfo(wsDocInfo);
        }
        wsDocInfo.setCrypto(cr);

        //
        // At first get the security token (certificate) according to the parameters.
        //
        X509Certificate[] certs = getSigningCerts();

        try {
            C14NMethodParameterSpec c14nSpec = null;
            if (addInclusivePrefixes && canonAlgo.equals(WSConstants.C14N_EXCL_OMIT_COMMENTS)) {
                Element securityHeaderElement = getSecurityHeader().getSecurityHeaderElement();
                List<String> prefixes =
                    getInclusivePrefixes(securityHeaderElement, false);
                c14nSpec = new ExcC14NParameterSpec(prefixes);
            }

           c14nMethod = signatureFactory.newCanonicalizationMethod(canonAlgo, c14nSpec);
        } catch (Exception ex) {
            LOG.error("", ex);
            throw new WSSecurityException(
                WSSecurityException.ErrorCode.FAILED_SIGNATURE, ex, "noXMLSig"
            );
        }

        keyInfoUri = getIdAllocator().createSecureId("KI-", keyInfo);
        if (!useCustomSecRef && customKeyInfoElement == null) {
            secRef = new SecurityTokenReference(getDocument());
            strUri = getIdAllocator().createSecureId("STR-", secRef);
            secRef.addWSSENamespace();
            secRef.addWSUNamespace();
            secRef.setID(strUri);

            //
            // Get an initialized XMLSignature element.
            //

            //
            // Prepare and setup the token references for this Signature
            //
            switch (keyIdentifierType) {
            case WSConstants.BST_DIRECT_REFERENCE:
                Reference ref = new Reference(getDocument());
                ref.setURI("#" + certUri);

                addBST(certs);
                if (!useSingleCert) {
                    secRef.addTokenType(PKIPathSecurity.PKI_TYPE);
                    ref.setValueType(PKIPathSecurity.PKI_TYPE);
                } else {
                    ref.setValueType(X509Security.X509_V3_TYPE);
                }
                secRef.setReference(ref);
                break;

            case WSConstants.ISSUER_SERIAL:
                String issuer = certs[0].getIssuerX500Principal().getName();
                java.math.BigInteger serialNumber = certs[0].getSerialNumber();
                DOMX509IssuerSerial domIssuerSerial =
                    new DOMX509IssuerSerial(getDocument(), issuer, serialNumber);
                DOMX509Data domX509Data = new DOMX509Data(getDocument(), domIssuerSerial);
                secRef.setUnknownElement(domX509Data.getElement());

                if (includeSignatureToken) {
                    addBST(certs);
                }
                break;

            case WSConstants.X509_KEY_IDENTIFIER:
                secRef.setKeyIdentifier(certs[0]);
                break;

            case WSConstants.SKI_KEY_IDENTIFIER:
                secRef.setKeyIdentifierSKI(certs[0], crypto);

                if (includeSignatureToken) {
                    addBST(certs);
                }
                break;

            case WSConstants.THUMBPRINT_IDENTIFIER:
                secRef.setKeyIdentifierThumb(certs[0]);

                if (includeSignatureToken) {
                    addBST(certs);
                }
                break;

            case WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER:
                if (encrKeySha1value != null) {
                    secRef.setKeyIdentifierEncKeySHA1(encrKeySha1value);
                } else {
                    byte[] digestBytes = KeyUtils.generateDigest(secretKey);
                    secRef.setKeyIdentifierEncKeySHA1(org.apache.xml.security.utils.XMLUtils.encodeToString(digestBytes));
                }
                secRef.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
                break;

            case WSConstants.CUSTOM_SYMM_SIGNING :
                Reference refCust = new Reference(getDocument());
                if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customTokenValueType)) {
                    secRef.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
                    refCust.setValueType(customTokenValueType);
                } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customTokenValueType)) {
                    secRef.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
                } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customTokenValueType)) {
                    secRef.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
                    refCust.setValueType(customTokenValueType);
                } else if (KerberosSecurity.isKerberosToken(customTokenValueType)) {
                    secRef.addTokenType(customTokenValueType);
                    refCust.setValueType(customTokenValueType);
                } else {
                    refCust.setValueType(customTokenValueType);
                }
                refCust.setURI("#" + customTokenId);
                secRef.setReference(refCust);
                break;

            case WSConstants.CUSTOM_SYMM_SIGNING_DIRECT :
                Reference refCustd = new Reference(getDocument());
                if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customTokenValueType)) {
                    secRef.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
                    refCustd.setValueType(customTokenValueType);
                } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customTokenValueType)) {
                    secRef.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
                } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customTokenValueType)) {
                    secRef.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
                    refCustd.setValueType(customTokenValueType);
                } else if (KerberosSecurity.isKerberosToken(customTokenValueType)) {
                    secRef.addTokenType(customTokenValueType);
                    refCustd.setValueType(customTokenValueType);
                } else {
                    refCustd.setValueType(customTokenValueType);
                }
                refCustd.setURI(customTokenId);
                secRef.setReference(refCustd);
                break;

            case WSConstants.CUSTOM_KEY_IDENTIFIER:
                if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customTokenValueType)) {
                    secRef.setKeyIdentifier(customTokenValueType, customTokenId);
                    secRef.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
                } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customTokenValueType)) {
                    secRef.setKeyIdentifier(customTokenValueType, customTokenId);
                    secRef.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
                } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customTokenValueType)) {
                    secRef.setKeyIdentifier(customTokenValueType, customTokenId, true);
                    secRef.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
                } else if (SecurityTokenReference.ENC_KEY_SHA1_URI.equals(customTokenValueType)) {
                    secRef.setKeyIdentifier(customTokenValueType, customTokenId, true);
                    secRef.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
                } else if (WSConstants.WSS_KRB_KI_VALUE_TYPE.equals(customTokenValueType)) {
                    secRef.setKeyIdentifier(customTokenValueType, customTokenId, true);
                    secRef.addTokenType(WSConstants.WSS_GSS_KRB_V5_AP_REQ);
                }
                break;

            case WSConstants.KEY_VALUE:
                java.security.PublicKey publicKey = certs[0].getPublicKey();

                try {
                    KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory();
                    KeyValue keyValue = keyInfoFactory.newKeyValue(publicKey);
                    keyInfo =
                        keyInfoFactory.newKeyInfo(Collections.singletonList(keyValue), keyInfoUri);
                } catch (java.security.KeyException ex) {
                    LOG.error("", ex);
                    throw new WSSecurityException(
                        WSSecurityException.ErrorCode.FAILED_SIGNATURE, ex, "noXMLSig"
                    );
                }
                break;
            default:
                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "unsupportedKeyId");
            }
        }

        if (keyIdentifierType != WSConstants.KEY_VALUE) {
            marshalKeyInfo(wsDocInfo);
        }
    }

    protected void marshalKeyInfo(WSDocInfo wsDocInfo) throws WSSecurityException {
        List<XMLStructure> kiChildren = null;
        if (customKeyInfoElement == null) {
            XMLStructure structure = new DOMStructure(secRef.getElement());
            wsDocInfo.addTokenElement(secRef.getElement(), false);
            kiChildren = Collections.singletonList(structure);
        } else {
            Node kiChild = customKeyInfoElement.getFirstChild();
            kiChildren = new ArrayList<>();
            while (kiChild != null) {
                kiChildren.add(new DOMStructure(kiChild));
                kiChild = kiChild.getNextSibling();
            }
        }

        KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory();
        keyInfo = keyInfoFactory.newKeyInfo(kiChildren, keyInfoUri);
    }

    /**
     * Builds a signed soap envelope.
     *
     * This is a convenience method and for backward compatibility. The method
     * creates a Signature and puts it into the Security header. It does so by
     * calling the single functions in order to perform a <i>one shot signature</i>.
     *
     * @param cr An instance of the Crypto API to handle keystore and certificates
     * @return A signed SOAP envelope as <code>Document</code>
     * @throws WSSecurityException
     */
    public Document build(Crypto cr)
        throws WSSecurityException {

        LOG.debug("Beginning signing...");

        prepare(cr);
        if (getParts().isEmpty()) {
            getParts().add(WSSecurityUtil.getDefaultEncryptionPart(getDocument()));
        } else {
            for (WSEncryptionPart part : getParts()) {
                if (part.getId() == null && "STRTransform".equals(part.getName())) {
                    part.setId(strUri);
                } else if ("KeyInfo".equals(part.getName()) && WSConstants.SIG_NS.equals(part.getNamespace())
                    && part.getElement() == null) {
                    // Special code to sign the KeyInfo
                    part.setId(keyInfoUri);
                }
            }
        }

        List<javax.xml.crypto.dsig.Reference> referenceList = addReferencesToSign(getParts());

        computeSignature(referenceList);

        //
        // if we have a BST prepend it in front of the Signature according to
        // strict layout rules.
        //
        if (bstToken != null) {
            prependBSTElementToHeader();
        }

        return getDocument();
    }


    /**
     * This method adds references to the Signature.
     *
     * @param references The list of references to sign
     * @throws WSSecurityException
     */
    public List<javax.xml.crypto.dsig.Reference> addReferencesToSign(
        List<WSEncryptionPart> references
    ) throws WSSecurityException {
        return
            addReferencesToSign(
                getDocument(),
                references,
                getWsDocInfo(),
                signatureFactory,
                addInclusivePrefixes,
                digestAlgo
            );
    }

    /**
     * Returns the SignatureElement.
     * The method can be called any time after <code>prepare()</code>.
     * @return The DOM Element of the signature.
     */
    public Element getSignatureElement() {
        Element securityHeaderElement = getSecurityHeader().getSecurityHeaderElement();
        return
            XMLUtils.getDirectChildElement(
                securityHeaderElement, WSConstants.SIG_LN, WSConstants.SIG_NS
            );
    }

    /**
     * Add a BinarySecurityToken
     */
    private void addBST(X509Certificate[] certs) throws WSSecurityException {
        if (storeBytesInAttachment) {
            bstToken =
                getDocument().createElementNS(WSS4JConstants.WSSE_NS, "wsse:BinarySecurityToken");
            bstToken.setAttributeNS(null, "EncodingType", WSS4JConstants.BASE64_ENCODING);
            bstToken.setAttributeNS(WSS4JConstants.WSU_NS, WSS4JConstants.WSU_PREFIX + ":Id", certUri);
            if (addWSUNamespace) {
                bstToken.setAttributeNS(XMLUtils.XMLNS_NS, "xmlns:" + WSConstants.WSU_PREFIX, WSConstants.WSU_NS);
            }

            byte[] certBytes = null;
            if (!useSingleCert) {
                bstToken.setAttributeNS(null, "ValueType", PKIPathSecurity.PKI_TYPE);
                certBytes = crypto.getBytesFromCertificates(certs);
            } else {
                bstToken.setAttributeNS(null, "ValueType", X509Security.X509_V3_TYPE);
                try {
                    certBytes = certs[0].getEncoded();
                } catch (CertificateEncodingException e) {
                    throw new WSSecurityException(
                        WSSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, e, "encodeError"
                    );
                }
            }

            final String attachmentId = getIdAllocator().createId("", getDocument());
            WSSecurityUtil.storeBytesInAttachment(bstToken, getDocument(), attachmentId,
                                                  certBytes, attachmentCallbackHandler);
            getWsDocInfo().addTokenElement(bstToken, false);
        } else {
            BinarySecurity binarySecurity = null;
            if (!useSingleCert) {
                binarySecurity = new PKIPathSecurity(getDocument());
                ((PKIPathSecurity) binarySecurity).setX509Certificates(certs, crypto);
            } else {
                binarySecurity = new X509Security(getDocument());
                ((X509Security) binarySecurity).setX509Certificate(certs[0]);
            }
            binarySecurity.setID(certUri);
            if (addWSUNamespace) {
                binarySecurity.addWSUNamespace();
            }
            bstToken = binarySecurity.getElement();
            getWsDocInfo().addTokenElement(bstToken, false);
        }

        bstAddedToSecurityHeader = false;
    }

    /**
     * Prepend the BinarySecurityToken to the elements already in the Security
     * header.
     *
     * The method can be called any time after <code>prepare()</code>.
     * This allows to insert the BST element at any position in the Security
     * header.
     */
    public void prependBSTElementToHeader() {
        if (bstToken != null && !bstAddedToSecurityHeader) {
            Element securityHeaderElement = getSecurityHeader().getSecurityHeaderElement();
            WSSecurityUtil.prependChildElement(securityHeaderElement, bstToken);
            bstAddedToSecurityHeader = true;
        }
    }

    /**
     * Append the BinarySecurityToken to the security header.
     */
    public void appendBSTElementToHeader() {
        if (bstToken != null && !bstAddedToSecurityHeader) {
            Element securityHeaderElement = getSecurityHeader().getSecurityHeaderElement();
            securityHeaderElement.appendChild(bstToken);
            bstAddedToSecurityHeader = true;
        }
    }

    /**
     * Compute the Signature over the references. The signature element will be
     * prepended to the security header.
     *
     * This method can be called any time after the references were set. See
     * <code>addReferencesToSign()</code>.
     *
     * @param referenceList The list of references to sign
     *
     * @throws WSSecurityException
     */
    public void computeSignature(
        List<javax.xml.crypto.dsig.Reference> referenceList
    ) throws WSSecurityException {
        computeSignature(referenceList, true, null);
    }

    /**
     * Compute the Signature over the references.
     *
     * This method can be called any time after the references were set. See
     * <code>addReferencesToSign()</code>.
     *
     * @param referenceList The list of references to sign
     * @param prepend Whether to prepend the signature element to the security header
     * @param siblingElement If prepending, then prepend before this sibling Element
     *
     * @throws WSSecurityException
     */
    public void computeSignature(
        List<javax.xml.crypto.dsig.Reference> referenceList,
        boolean prepend,
        Element siblingElement
    ) throws WSSecurityException {
        try {
            java.security.Key key;
            if (secretKey == null) {
                key = crypto.getPrivateKey(user, password);
            } else {
                key = KeyUtils.prepareSecretKey(sigAlgo, secretKey);
            }
            SignatureMethod signatureMethod =
                signatureFactory.newSignatureMethod(sigAlgo, null);
            SignedInfo signedInfo =
                signatureFactory.newSignedInfo(c14nMethod, signatureMethod, referenceList);

            sig = signatureFactory.newXMLSignature(
                    signedInfo,
                    keyInfo,
                    null,
                    getIdAllocator().createId("SIG-", null),
                    null);

            //
            // Figure out where to insert the signature element
            //
            XMLSignContext signContext = null;
            Element securityHeaderElement = getSecurityHeader().getSecurityHeaderElement();
            if (prepend) {
                if (siblingElement == null) {
                    Node child = securityHeaderElement.getFirstChild();
                    while (child != null && child.getNodeType() != Node.ELEMENT_NODE) {
                        child = child.getNextSibling();
                    }
                    siblingElement = (Element)child;
                }
                if (siblingElement == null) {
                    signContext = new DOMSignContext(key, securityHeaderElement);
                } else {
                    signContext = new DOMSignContext(key, securityHeaderElement, siblingElement);
                }
            } else {
                signContext = new DOMSignContext(key, securityHeaderElement);
            }
            if (signatureProvider != null) {
                signContext.setProperty("org.jcp.xml.dsig.internal.dom.SignatureProvider", signatureProvider);
            }

            signContext.putNamespacePrefix(WSConstants.SIG_NS, WSConstants.SIG_PREFIX);
            if (WSConstants.C14N_EXCL_OMIT_COMMENTS.equals(canonAlgo)) {
                signContext.putNamespacePrefix(
                    WSConstants.C14N_EXCL_OMIT_COMMENTS,
                    WSConstants.C14N_EXCL_OMIT_COMMENTS_PREFIX
                );
            }
            signContext.setProperty(STRTransform.TRANSFORM_WS_DOC_INFO, getWsDocInfo());
            getWsDocInfo().setCallbackLookup(callbackLookup);

            // Add the elements to sign to the Signature Context
            getWsDocInfo().setTokensOnContext((DOMSignContext)signContext);
            sig.sign(signContext);

            signatureValue = sig.getSignatureValue().getValue();

            cleanup();
        } catch (Exception ex) {
            LOG.error(ex.getMessage(), ex);
            throw new WSSecurityException(
                WSSecurityException.ErrorCode.FAILED_SIGNATURE, ex
            );
        }
    }

    /**
     * Set the single cert flag.
     *
     * @param useSingleCert
     */
    public void setUseSingleCertificate(boolean useSingleCert) {
        this.useSingleCert = useSingleCert;
    }

    /**
     * Get the single cert flag.
     *
     * @return A boolean if single certificate is set.
     */
    public boolean isUseSingleCertificate() {
        return useSingleCert;
    }

    /**
     * Set the name (uri) of the signature encryption algorithm to use.
     *
     * If the algorithm is not set then an automatic detection of the signature
     * algorithm to use is performed during the <code>prepare()</code>
     * method. Refer to WSConstants which algorithms are supported.
     *
     * @param algo the name of the signature algorithm
     * @see WSConstants#RSA
     * @see WSConstants#DSA
     */
    public void setSignatureAlgorithm(String algo) {
        sigAlgo = algo;
    }

    /**
     * Get the name (uri) of the signature algorithm that is being used.
     *
     * Call this method after <code>prepare</code> to get the information
     * which signature algorithm was automatically detected if no signature
     * algorithm was preset.
     *
     * @return the identifier URI of the signature algorithm
     */
    public String getSignatureAlgorithm() {
        return sigAlgo;
    }

    /**
     * Set the canonicalization method to use.
     *
     * If the canonicalization method is not set then the recommended Exclusive
     * XML Canonicalization is used by default. Refer to WSConstants which
     * algorithms are supported.
     *
     * @param algo Is the name of the signature algorithm
     * @see WSConstants#C14N_OMIT_COMMENTS
     * @see WSConstants#C14N_WITH_COMMENTS
     * @see WSConstants#C14N_EXCL_OMIT_COMMENTS
     * @see WSConstants#C14N_EXCL_WITH_COMMENTS
     */
    public void setSigCanonicalization(String algo) {
        canonAlgo = algo;
    }

    /**
     * Get the canonicalization method.
     *
     * If the canonicalization method was not set then Exclusive XML
     * Canonicalization is used by default.
     *
     * @return The string describing the canonicalization algorithm.
     */
    public String getSigCanonicalization() {
        return canonAlgo;
    }

    /**
     * @return the digest algorithm to use
     */
    public String getDigestAlgo() {
        return digestAlgo;
    }

    /**
     * Set the string that defines which digest algorithm to use.
     * The default is WSConstants.SHA1.
     *
     * @param digestAlgo the digestAlgo to set
     */
    public void setDigestAlgo(String digestAlgo) {
        this.digestAlgo = digestAlgo;
    }


    /**
     * Returns the computed Signature value.
     *
     * Call this method after <code>computeSignature()</code> or <code>build()</code>
     * methods were called.
     *
     * @return Returns the signatureValue.
     */
    public byte[] getSignatureValue() {
        return signatureValue;
    }

    /**
     * Get the id generated during <code>prepare()</code>.
     *
     * Returns the the value of wsu:Id attribute of the Signature element.
     *
     * @return Return the wsu:Id of this token or null if <code>prepare()</code>
     *         was not called before.
     */
    public String getId() {
        if (sig == null) {
            return null;
        }
        return sig.getId();
    }

    /**
     * Get the id of the BST generated  during <code>prepare()</code>.
     *
     * @return Returns the the value of wsu:Id attribute of the
     * BinaruSecurityToken element.
     */
    public String getBSTTokenId() {
        if (bstToken == null) {
            return null;
        }
        return bstToken.getAttributeNS(WSS4JConstants.WSU_NS, "Id");
    }

    /**
     * Set the secret key to use
     * @param secretKey the secret key to use
     */
    public void setSecretKey(byte[] secretKey) {
        this.secretKey = secretKey;
    }

    /**
     * Set the custom token value type to use
     * @param customTokenValueType the custom token value type to use
     */
    public void setCustomTokenValueType(String customTokenValueType) {
        this.customTokenValueType = customTokenValueType;
    }

    /**
     * Set the custom token id
     * @param customTokenId the custom token id
     */
    public void setCustomTokenId(String customTokenId) {
        this.customTokenId = customTokenId;
    }

    public String getCustomTokenId() {
        return this.customTokenId;
    }

    /**
     * Set the encrypted key sha1 value
     * @param encrKeySha1value the encrypted key sha1 value
     */
    public void setEncrKeySha1value(String encrKeySha1value) {
        this.encrKeySha1value = encrKeySha1value;
    }

    /**
     * Set the X509 Certificate to use
     * @param cer the X509 Certificate to use
     */
    public void setX509Certificate(X509Certificate cer) {
        this.useThisCert = cer;
    }

    /**
     * Returns the BST Token element.
     * The method can be called any time after <code>prepare()</code>.
     * @return the BST Token element
     */
    public Element getBinarySecurityTokenElement() {
        return bstToken;
    }

    /**
     * @return the URI associated with the SecurityTokenReference
     * (must be called after {@link #prepare(Document, Crypto)}
     */
    public String getSecurityTokenReferenceURI() {
        return strUri;
    }

    /**
     * Get the SecurityTokenReference to be used in the KeyInfo element.
     */
    public SecurityTokenReference getSecurityTokenReference() {
        return secRef;
    }

    /**
     * Set the SecurityTokenReference to be used in the KeyInfo element. If this
     * method is not called, a SecurityTokenRefence will be generated.
     */
    public void setSecurityTokenReference(SecurityTokenReference secRef) {
        useCustomSecRef = true;
        this.secRef = secRef;
    }

    /**
     * Set up the X509 Certificate(s) for signing.
     */
    private X509Certificate[] getSigningCerts() throws WSSecurityException {
        X509Certificate[] certs = null;
        if (!(keyIdentifierType == WSConstants.CUSTOM_SYMM_SIGNING
            || keyIdentifierType == WSConstants.CUSTOM_SYMM_SIGNING_DIRECT
            || keyIdentifierType == WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER
            || keyIdentifierType == WSConstants.CUSTOM_KEY_IDENTIFIER)) {
            if (useThisCert == null) {
                CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
                cryptoType.setAlias(user);
                if (crypto == null) {
                    throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noSigCryptoFile");
                }
                certs = crypto.getX509Certificates(cryptoType);
            } else {
                certs = new X509Certificate[] {useThisCert};
            }
            if (certs == null || certs.length <= 0) {
                throw new WSSecurityException(
                        WSSecurityException.ErrorCode.FAILURE,
                        "noUserCertsFound",
                        new Object[] {user, "signature"});
            }
            certUri = getIdAllocator().createSecureId("X509-", certs[0]);
            //
            // If no signature algorithm was set try to detect it according to the
            // data stored in the certificate.
            //
            if (sigAlgo == null) {
                String pubKeyAlgo = certs[0].getPublicKey().getAlgorithm();
                LOG.debug("Automatic signature algorithm detection: {}", pubKeyAlgo);
                if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
                    sigAlgo = WSConstants.DSA;
                } else if (pubKeyAlgo.equalsIgnoreCase("RSA")) {
                    sigAlgo = WSConstants.RSA;
                } else if (pubKeyAlgo.equalsIgnoreCase("EC")) {
                    sigAlgo = WSConstants.ECDSA_SHA256;
                } else {
                    throw new WSSecurityException(
                        WSSecurityException.ErrorCode.FAILURE,
                        "unknownSignatureAlgorithm",
                        new Object[] {pubKeyAlgo});
                }
            }
        }
        return certs;
    }

    public boolean isIncludeSignatureToken() {
        return includeSignatureToken;
    }

    public void setIncludeSignatureToken(boolean includeSignatureToken) {
        this.includeSignatureToken = includeSignatureToken;
    }

    public boolean isAddInclusivePrefixes() {
        return addInclusivePrefixes;
    }

    public void setAddInclusivePrefixes(boolean addInclusivePrefixes) {
        this.addInclusivePrefixes = addInclusivePrefixes;
    }

    public void setCustomKeyInfoElement(Element keyInfoElement) {
        this.customKeyInfoElement = keyInfoElement;
    }

    public Element getCustomKeyInfoElement() {
        return customKeyInfoElement;
    }

    public Provider getSignatureProvider() {
        return signatureProvider;
    }

    public void setSignatureProvider(Provider signatureProvider) {
        this.signatureProvider = signatureProvider;
    }

    public String getKeyInfoUri() {
        return keyInfoUri;
    }
}
