/**
 * 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.saml;

import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.List;

import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.XMLSignContext;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.ExcC14NParameterSpec;

import org.apache.wss4j.common.SignatureActionToken;
import org.apache.wss4j.common.WSEncryptionPart;
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.saml.OpenSAMLUtil;
import org.apache.wss4j.common.saml.SAMLKeyInfo;
import org.apache.wss4j.common.saml.SAMLUtil;
import org.apache.wss4j.common.saml.SamlAssertionWrapper;
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.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.dom.WSConstants;
import org.apache.wss4j.dom.WSDocInfo;
import org.apache.wss4j.dom.handler.RequestData;
import org.apache.wss4j.dom.message.WSSecHeader;
import org.apache.wss4j.dom.message.WSSecSignature;
import org.apache.wss4j.dom.transform.STRTransform;
import org.apache.wss4j.dom.util.WSSecurityUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class WSSecSignatureSAML extends WSSecSignature {

    private static final org.slf4j.Logger LOG =
        org.slf4j.LoggerFactory.getLogger(WSSecSignatureSAML.class);
    private boolean senderVouches;
    private SecurityTokenReference secRefSaml;
    private String secRefID;
    private Element samlToken;
    private Crypto userCrypto;
    private Crypto issuerCrypto;
    private String issuerKeyName;
    private String issuerKeyPW;
    private boolean useDirectReferenceToAssertion;

    /**
     * Constructor.
     */
    public WSSecSignatureSAML(WSSecHeader securityHeader) {
        super(securityHeader);
    }

    public WSSecSignatureSAML(Document doc) {
        super(doc);
    }

    /**
     * Builds a signed soap envelope with SAML token.
     *
     * The method first gets an appropriate security header. According to the
     * defined parameters for certificate handling the signature elements are
     * constructed and inserted into the <code>wsse:Signature</code>
     *
     * @param uCrypto
     *            The user's Crypto instance
     * @param samlAssertion
     *            the complete SAML assertion
     * @param iCrypto
     *            An instance of the Crypto API to handle keystore SAML token
     *            issuer and to generate certificates
     * @param iKeyName
     *            Private key to use in case of "sender-Vouches"
     * @param iKeyPW
     *            Password for issuer private key
     * @return A signed SOAP envelope as <code>Document</code>
     * @throws WSSecurityException
     */
    public Document build(
        Crypto uCrypto, SamlAssertionWrapper samlAssertion,
        Crypto iCrypto, String iKeyName, String iKeyPW
    ) throws WSSecurityException {

        prepare(uCrypto, samlAssertion, iCrypto, iKeyName, iKeyPW);

        if (getParts().isEmpty()) {
            getParts().add(WSSecurityUtil.getDefaultEncryptionPart(getDocument()));
        } else {
            for (WSEncryptionPart part : getParts()) {
                if ("STRTransform".equals(part.getName()) && part.getId() == null) {
                    part.setId(strUri);
                }
            }
        }

        //
        // Add the STRTransform for the SecurityTokenReference to the SAML assertion
        // if it exists
        //
        if (secRefID != null) {
            String soapNamespace =
                WSSecurityUtil.getSOAPNamespace(getDocument().getDocumentElement());
            WSEncryptionPart encP =
                new WSEncryptionPart("STRTransform", soapNamespace, "Content");
            encP.setId(secRefID);
            getParts().add(encP);
        }

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

        prependSAMLElementsToHeader();

        if (senderVouches) {
            computeSignature(referenceList, secRefSaml.getElement());
        } else {
            computeSignature(referenceList, samlToken);
        }

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

        return getDocument();
    }

    /**
     * Initialize a WSSec SAML Signature.
     *
     * The method sets up and initializes a WSSec SAML 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 uCrypto
     *            The user's Crypto instance
     * @param samlAssertion
     *            the complete SAML assertion
     * @param iCrypto
     *            An instance of the Crypto API to handle keystore SAML token
     *            issuer and to generate certificates
     * @param iKeyName
     *            Private key to use in case of "sender-Vouches"
     * @param iKeyPW
     *            Password for issuer private key
     * @throws WSSecurityException
     */
    public void prepare(
        Crypto uCrypto, SamlAssertionWrapper samlAssertion, Crypto iCrypto,
        String iKeyName, String iKeyPW
    ) throws WSSecurityException {

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

        userCrypto = uCrypto;
        issuerCrypto = iCrypto;
        issuerKeyName = iKeyName;
        issuerKeyPW = iKeyPW;

        samlToken = samlAssertion.toDOM(getDocument());

        //
        // Get some information about the SAML token content. This controls how
        // to deal with the whole stuff. First get the Authentication statement
        // (includes Subject), then get the _first_ confirmation method only
        // thats if "senderVouches" is true.
        //
        String confirmMethod = null;
        List<String> methods = samlAssertion.getConfirmationMethods();
        if (methods != null && !methods.isEmpty()) {
            confirmMethod = methods.get(0);
        }
        if (OpenSAMLUtil.isMethodSenderVouches(confirmMethod)) {
            senderVouches = true;
        }
        //
        // Gather some info about the document to process and store it for
        // retrieval
        //
        if (super.getWsDocInfo() == null) {
            WSDocInfo wsDocInfo = new WSDocInfo(getDocument());
            super.setWsDocInfo(wsDocInfo);
        }


        X509Certificate[] certs = null;
        PublicKey publicKey = null;

        if (senderVouches) {
            CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
            cryptoType.setAlias(issuerKeyName);
            certs = issuerCrypto.getX509Certificates(cryptoType);
            getWsDocInfo().setCrypto(issuerCrypto);
        } else {
            //
            // in case of key holder: - get the user's certificate that _must_ be
            // included in the SAML token. To ensure the cert integrity the SAML
            // token must be signed (by the issuer).
            //
            if (userCrypto == null || !samlAssertion.isSigned()) {
                throw new WSSecurityException(
                    WSSecurityException.ErrorCode.FAILURE,
                    "invalidSAMLsecurity",
                    new Object[] {"for SAML Signature (Key Holder)"});
            }
            if (secretKey == null) {
                RequestData data = new RequestData();
                data.setWsDocInfo(getWsDocInfo());
                SignatureActionToken actionToken = new SignatureActionToken();
                data.setSignatureToken(actionToken);
                actionToken.setCrypto(userCrypto);
                SAMLKeyInfo samlKeyInfo =
                    SAMLUtil.getCredentialFromSubject(
                            samlAssertion, new WSSSAMLKeyInfoProcessor(data),
                            userCrypto, data.getCallbackHandler()
                    );
                if (samlKeyInfo != null) {
                    publicKey = samlKeyInfo.getPublicKey();
                    certs = samlKeyInfo.getCerts();
                    getWsDocInfo().setCrypto(userCrypto);
                }
            }
        }
        if ((certs == null || certs.length == 0 || certs[0] == null)
            && publicKey == null && secretKey == null) {
            throw new WSSecurityException(
                WSSecurityException.ErrorCode.FAILURE,
                "noCertsFound",
                new Object[] {"SAML signature"});
        }

        if (getSignatureAlgorithm() == null) {
            PublicKey key = null;
            if (certs != null && certs[0] != null) {
                key = certs[0].getPublicKey();
            } else if (publicKey != null) {
                key = publicKey;
            } else {
                throw new WSSecurityException(
                    WSSecurityException.ErrorCode.FAILURE, "unknownSignatureAlgorithm"
                );
            }

            String pubKeyAlgo = key.getAlgorithm();
            LOG.debug("automatic sig algo detection: {}", pubKeyAlgo);
            if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
                setSignatureAlgorithm(WSConstants.DSA);
            } else if (pubKeyAlgo.equalsIgnoreCase("RSA")) {
                setSignatureAlgorithm(WSConstants.RSA);
            } else {
                throw new WSSecurityException(
                    WSSecurityException.ErrorCode.FAILURE,
                    "unknownSignatureAlgorithm",
                    new Object[] {pubKeyAlgo});
            }
        }
        sig = null;

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

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

        keyInfoUri = getIdAllocator().createSecureId("KeyId-", keyInfo);
        SecurityTokenReference secRef = new SecurityTokenReference(getDocument());
        strUri = getIdAllocator().createSecureId("STRId-", secRef);
        secRef.setID(strUri);
        setSecurityTokenReference(secRef);

        if (certs != null && certs.length != 0) {
            certUri = getIdAllocator().createSecureId("CertId-", certs[0]);
        }

        //
        // If the sender vouches, then we must sign the SAML token _and_ at
        // least one part of the message (usually the SOAP body). To do so we
        // need to - put in a reference to the SAML token. Thus we create a STR
        // and insert it into the wsse:Security header - set a reference of the
        // created STR to the signature and use STR Transform during the
        // signature
        //
        try {
            if (senderVouches) {
                secRefSaml = new SecurityTokenReference(getDocument());
                secRefID = getIdAllocator().createSecureId("STRSAMLId-", secRefSaml);
                secRefSaml.setID(secRefID);

                if (useDirectReferenceToAssertion) {
                    Reference ref = new Reference(getDocument());
                    ref.setURI("#" + samlAssertion.getId());
                    if (samlAssertion.getSaml1() != null) {
                        ref.setValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
                        secRefSaml.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
                    } else if (samlAssertion.getSaml2() != null) {
                        secRefSaml.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
                    }
                    secRefSaml.setReference(ref);
                } else {
                    Element keyId = getDocument().createElementNS(WSConstants.WSSE_NS, "wsse:KeyIdentifier");
                    String valueType = null;
                    if (samlAssertion.getSaml1() != null) {
                        valueType = WSConstants.WSS_SAML_KI_VALUE_TYPE;
                        secRefSaml.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
                    } else if (samlAssertion.getSaml2() != null) {
                        valueType = WSConstants.WSS_SAML2_KI_VALUE_TYPE;
                        secRefSaml.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
                    }
                    keyId.setAttributeNS(
                        null, "ValueType", valueType
                    );
                    keyId.appendChild(getDocument().createTextNode(samlAssertion.getId()));
                    Element elem = secRefSaml.getElement();
                    elem.appendChild(keyId);
                }
                getWsDocInfo().addTokenElement(secRefSaml.getElement(), false);
            }
        } catch (Exception ex) {
            throw new WSSecurityException(
                WSSecurityException.ErrorCode.FAILED_SIGNATURE, ex, "noXMLSig"
            );
        }

        X509Certificate cert = certs != null ? certs[0] : null;
        configureKeyInfo(secRef, cert, iCrypto != null ? iCrypto : uCrypto, samlAssertion);

        getWsDocInfo().addTokenElement(samlToken, false);
    }

    private void configureKeyInfo(
        SecurityTokenReference secRef, X509Certificate cert,
        Crypto crypto, SamlAssertionWrapper samlAssertion
    ) throws WSSecurityException {
        if (getCustomKeyInfoElement() == null) {
            if (senderVouches) {
                switch (keyIdentifierType) {
                case WSConstants.BST_DIRECT_REFERENCE:
                    Reference ref = new Reference(getDocument());
                    ref.setURI("#" + certUri);
                    BinarySecurity binarySecurity = new X509Security(getDocument());
                    ((X509Security) binarySecurity).setX509Certificate(cert);
                    binarySecurity.setID(certUri);
                    bstToken = binarySecurity.getElement();
                    getWsDocInfo().addTokenElement(bstToken, false);
                    ref.setValueType(binarySecurity.getValueType());
                    secRef.setReference(ref);
                    break;

                case WSConstants.X509_KEY_IDENTIFIER :
                    secRef.setKeyIdentifier(cert);
                    break;

                case WSConstants.SKI_KEY_IDENTIFIER:
                    secRef.setKeyIdentifierSKI(cert, crypto);
                    break;

                case WSConstants.THUMBPRINT_IDENTIFIER:
                    secRef.setKeyIdentifierThumb(cert);
                    break;

                    case WSConstants.ISSUER_SERIAL:
                        addIssuerSerial(cert, secRef, false);
                        break;
                    case WSConstants.ISSUER_SERIAL_QUOTE_FORMAT:
                        addIssuerSerial(cert, secRef, true);
                        break;

                default:
                    throw new WSSecurityException(
                        WSSecurityException.ErrorCode.FAILURE, "unsupportedKeyId"
                    );
                }
            } else if (useDirectReferenceToAssertion) {
                Reference ref = new Reference(getDocument());
                ref.setURI("#" + samlAssertion.getId());
                if (samlAssertion.getSaml1() != null) {
                    ref.setValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
                    secRef.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
                } else if (samlAssertion.getSaml2() != null) {
                    secRef.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
                }
                secRef.setReference(ref);
            } else {
                Element keyId = getDocument().createElementNS(WSConstants.WSSE_NS, "wsse:KeyIdentifier");
                String valueType = null;
                if (samlAssertion.getSaml1() != null) {
                    valueType = WSConstants.WSS_SAML_KI_VALUE_TYPE;
                    secRef.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
                } else if (samlAssertion.getSaml2() != null) {
                    valueType = WSConstants.WSS_SAML2_KI_VALUE_TYPE;
                    secRef.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
                }
                keyId.setAttributeNS(
                    null, "ValueType", valueType
                );
                keyId.appendChild(getDocument().createTextNode(samlAssertion.getId()));
                Element elem = secRef.getElement();
                elem.appendChild(keyId);
            }
        }

        marshalKeyInfo(getWsDocInfo());
    }

    private void addIssuerSerial(X509Certificate cert, SecurityTokenReference secRef, boolean isQuoteDelimited) {
        final String issuer = cert.getIssuerDN().getName();
        final java.math.BigInteger serialNumber = cert.getSerialNumber();
        final DOMX509IssuerSerial domIssuerSerial =
                new DOMX509IssuerSerial(getDocument(), issuer, serialNumber, isQuoteDelimited);
        final DOMX509Data domX509Data = new DOMX509Data(getDocument(), domIssuerSerial);
        secRef.setUnknownElement(domX509Data.getElement());
    }

    /**
     * Prepend the SAML elements to the elements already in the Security header.
     *
     * The method can be called any time after <code>prepare()</code>. This
     * allows to insert the SAML elements at any position in the Security
     * header.
     *
     * This methods first prepends the SAML security reference if mode is
     * <code>senderVouches</code>, then the SAML token itself,
     */
    public void prependSAMLElementsToHeader() {
        Element securityHeaderElement = getSecurityHeader().getSecurityHeaderElement();
        if (senderVouches) {
            WSSecurityUtil.prependChildElement(securityHeaderElement, secRefSaml.getElement());
        }

        WSSecurityUtil.prependChildElement(securityHeaderElement, samlToken);
    }


    /**
     * Compute the Signature over the references.
     *
     * After references are set this method computes the Signature for them.
     * This method can be called any time after the references were set. See
     * <code>addReferencesToSign()</code>.
     *
     * @throws WSSecurityException
     */
    public void computeSignature(
        List<javax.xml.crypto.dsig.Reference> referenceList,
        Element siblingElement
    ) throws WSSecurityException {
        try {
            java.security.Key key;
            if (senderVouches) {
                key = issuerCrypto.getPrivateKey(issuerKeyName, issuerKeyPW);
            } else if (secretKey != null) {
                key = KeyUtils.prepareSecretKey(getSignatureAlgorithm(), secretKey);
            } else {
                key = userCrypto.getPrivateKey(user, password);
            }
            SignatureMethod signatureMethod =
                signatureFactory.newSignatureMethod(getSignatureAlgorithm(), null);
            SignedInfo signedInfo =
                signatureFactory.newSignedInfo(c14nMethod, signatureMethod, referenceList);

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

            Element securityHeaderElement = getSecurityHeader().getSecurityHeaderElement();
            //
            // Prepend the signature element to the security header (after the assertion)
            //
            XMLSignContext signContext = null;
            if (siblingElement != null && siblingElement.getNextSibling() != null) {
                signContext =
                    new DOMSignContext(key, securityHeaderElement, siblingElement.getNextSibling());
            } else {
                signContext = new DOMSignContext(key, securityHeaderElement);
            }
            if (getSignatureProvider() != null) {
                signContext.setProperty("org.jcp.xml.dsig.internal.dom.SignatureProvider", getSignatureProvider());
            }

            signContext.putNamespacePrefix(WSConstants.SIG_NS, WSConstants.SIG_PREFIX);
            if (WSConstants.C14N_EXCL_OMIT_COMMENTS.equals(getSigCanonicalization())) {
                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();

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

    /**
     * Return whether a Direct Reference is to be used to reference the assertion. The
     * default is false.
     * @return whether a Direct Reference is to be used to reference the assertion
     */
    public boolean isUseDirectReferenceToAssertion() {
        return useDirectReferenceToAssertion;
    }

    /**
     * Set whether a Direct Reference is to be used to reference the assertion. The
     * default is false.
     * @param useDirectReferenceToAssertion whether a Direct Reference is to be used
     *        to reference the assertion
     */
    public void setUseDirectReferenceToAssertion(boolean useDirectReferenceToAssertion) {
        this.useDirectReferenceToAssertion = useDirectReferenceToAssertion;
    }

}
