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

import java.security.Key;
import java.security.NoSuchProviderException;
import java.security.Principal;
import java.security.Provider;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.security.spec.AlgorithmParameterSpec;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.xml.crypto.Data;
import javax.xml.crypto.NodeSetData;
import javax.xml.crypto.OctetStreamData;
import javax.xml.crypto.dsig.Manifest;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLObject;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.XMLValidateContext;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.spec.ExcC14NParameterSpec;
import javax.xml.crypto.dsig.spec.HMACParameterSpec;

import org.apache.wss4j.common.bsp.BSPEnforcer;
import org.apache.wss4j.common.bsp.BSPRule;
import org.apache.wss4j.common.cache.ReplayCache;
import org.apache.wss4j.common.crypto.AlgorithmSuite;
import org.apache.wss4j.common.crypto.AlgorithmSuiteValidator;
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.principal.PublicKeyPrincipalImpl;
import org.apache.wss4j.common.principal.UsernameTokenPrincipal;
import org.apache.wss4j.common.principal.WSDerivedKeyTokenPrincipal;
import org.apache.wss4j.common.token.BinarySecurity;
import org.apache.wss4j.common.token.SecurityTokenReference;
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.WSDataRef;
import org.apache.wss4j.dom.WSDocInfo;
import org.apache.wss4j.dom.callback.CallbackLookup;
import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
import org.apache.wss4j.dom.handler.RequestData;
import org.apache.wss4j.dom.message.token.Timestamp;
import org.apache.wss4j.dom.str.STRParser;
import org.apache.wss4j.dom.str.STRParser.REFERENCE_TYPE;
import org.apache.wss4j.dom.str.STRParserParameters;
import org.apache.wss4j.dom.str.STRParserResult;
import org.apache.wss4j.dom.str.SignatureSTRParser;
import org.apache.wss4j.dom.transform.AttachmentContentSignatureTransform;
import org.apache.wss4j.dom.transform.STRTransform;
import org.apache.wss4j.dom.transform.STRTransformUtil;
import org.apache.wss4j.dom.util.EncryptionUtils;
import org.apache.wss4j.dom.util.WSSecurityUtil;
import org.apache.wss4j.dom.util.X509Util;
import org.apache.wss4j.dom.validate.Credential;
import org.apache.wss4j.dom.validate.Validator;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

public class SignatureProcessor implements Processor {
    private static final org.slf4j.Logger LOG =
        org.slf4j.LoggerFactory.getLogger(SignatureProcessor.class);

    private XMLSignatureFactory signatureFactory;

    public SignatureProcessor() {
        init(null);
    }

    public SignatureProcessor(Provider provider) {
        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);
        }
    }

    public List<WSSecurityEngineResult> handleToken(
        Element elem,
        RequestData data
    ) throws WSSecurityException {
        LOG.debug("Found signature element");
        Element keyInfoElement =
            XMLUtils.getDirectChildElement(
                elem,
                "KeyInfo",
                WSConstants.SIG_NS
            );
        X509Certificate[] certs = null;
        Principal principal = null;
        PublicKey publicKey = null;
        byte[] secretKey = null;
        String signatureMethod = getSignatureMethod(elem);
        REFERENCE_TYPE referenceType = null;

        Credential credential = new Credential();
        Validator validator = data.getValidator(WSConstants.SIGNATURE);
        if (keyInfoElement == null) {
            certs = getDefaultCerts(data.getSigVerCrypto());
            principal = certs[0].getSubjectX500Principal();
        } else {
            int result = 0;
            Node node = keyInfoElement.getFirstChild();
            Element child = null;
            while (node != null) {
                if (Node.ELEMENT_NODE == node.getNodeType()) {
                    result++;
                    child = (Element)node;
                }
                node = node.getNextSibling();
            }
            if (result != 1) {
                data.getBSPEnforcer().handleBSPRule(BSPRule.R5402);
            }

            if (!(SecurityTokenReference.SECURITY_TOKEN_REFERENCE.equals(child.getLocalName())
                && WSConstants.WSSE_NS.equals(child.getNamespaceURI()))) {
                data.getBSPEnforcer().handleBSPRule(BSPRule.R5417);

                publicKey = X509Util.parseKeyValue(keyInfoElement, signatureFactory);
                if (validator != null) {
                    credential.setPublicKey(publicKey);
                    principal = new PublicKeyPrincipalImpl(publicKey);
                    credential.setPrincipal(principal);
                    credential = validator.validate(credential, data);
                }
            } else {
                STRParserParameters parameters = new STRParserParameters();
                parameters.setData(data);
                parameters.setStrElement(child);
                if (signatureMethod != null) {
                    parameters.setDerivationKeyLength(KeyUtils.getKeyLength(signatureMethod));
                }

                STRParser strParser = new SignatureSTRParser();
                STRParserResult parserResult = strParser.parseSecurityTokenReference(parameters);
                principal = parserResult.getPrincipal();
                certs = parserResult.getCertificates();
                publicKey = parserResult.getPublicKey();
                secretKey = parserResult.getSecretKey();
                referenceType = parserResult.getCertificatesReferenceType();

                boolean trusted = parserResult.isTrustedCredential();
                if (trusted) {
                    LOG.debug("Direct Trust for SAML/BST credential");
                }
                if (!trusted && (publicKey != null || certs != null) && validator != null) {
                    credential.setPublicKey(publicKey);
                    credential.setCertificates(certs);
                    credential.setPrincipal(principal);
                    credential = validator.validate(credential, data);
                }
            }
        }

        //
        // Check that we have a certificate, a public key or a secret key with which to
        // perform signature verification
        //
        if ((certs == null || certs.length == 0 || certs[0] == null)
            && secretKey == null
            && publicKey == null) {
            LOG.debug("No certificates or keys were found with which to validate the signature");
            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
        }

        // Check for compliance against the defined AlgorithmSuite
        AlgorithmSuite algorithmSuite = data.getAlgorithmSuite();
        if (algorithmSuite != null) {
            AlgorithmSuiteValidator algorithmSuiteValidator = new
                AlgorithmSuiteValidator(algorithmSuite);

            if (principal instanceof WSDerivedKeyTokenPrincipal) {
                algorithmSuiteValidator.checkDerivedKeyAlgorithm(
                    ((WSDerivedKeyTokenPrincipal)principal).getAlgorithm()
                );
                algorithmSuiteValidator.checkSignatureDerivedKeyLength(
                    ((WSDerivedKeyTokenPrincipal)principal).getLength()
                );
            } else {
                if (certs != null && certs.length > 0) {
                    algorithmSuiteValidator.checkAsymmetricKeyLength(certs);
                } else if (publicKey != null) {
                    algorithmSuiteValidator.checkAsymmetricKeyLength(publicKey);
                } else if (secretKey != null) {
                    algorithmSuiteValidator.checkSymmetricKeyLength(secretKey.length);
                }
            }
        }

        XMLSignature xmlSignature =
            verifyXMLSignature(elem, certs, publicKey, secretKey, signatureMethod, data, data.getWsDocInfo());
        byte[] signatureValue = xmlSignature.getSignatureValue().getValue();
        String c14nMethod = xmlSignature.getSignedInfo().getCanonicalizationMethod().getAlgorithm();

        List<WSDataRef> dataRefs =
            buildProtectedRefs(
                elem.getOwnerDocument(), xmlSignature.getSignedInfo(), data, data.getWsDocInfo()
            );
        if (dataRefs.isEmpty()) {
            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
        }

        int actionPerformed = WSConstants.SIGN;
        if (principal instanceof UsernameTokenPrincipal) {
            actionPerformed = WSConstants.UT_SIGN;
        }

        WSSecurityEngineResult result = new WSSecurityEngineResult(
                actionPerformed, principal,
                certs, dataRefs, signatureValue);
        result.put(WSSecurityEngineResult.TAG_SIGNATURE_METHOD, signatureMethod);
        result.put(WSSecurityEngineResult.TAG_CANONICALIZATION_METHOD, c14nMethod);
        String tokenId = elem.getAttributeNS(null, "Id");
        if (!"".equals(tokenId)) {
            result.put(WSSecurityEngineResult.TAG_ID, tokenId);
        }
        result.put(WSSecurityEngineResult.TAG_SECRET, secretKey);
        result.put(WSSecurityEngineResult.TAG_PUBLIC_KEY, publicKey);
        result.put(WSSecurityEngineResult.TAG_X509_REFERENCE_TYPE, referenceType);
        result.put(WSSecurityEngineResult.TAG_TOKEN_ELEMENT, elem);
        if (validator != null) {
            result.put(WSSecurityEngineResult.TAG_VALIDATED_TOKEN, Boolean.TRUE);
            if (credential != null) {
                result.put(WSSecurityEngineResult.TAG_SUBJECT, credential.getSubject());
            }
        }
        data.getWsDocInfo().addResult(result);
        data.getWsDocInfo().addTokenElement(elem);
        return java.util.Collections.singletonList(result);
    }

    /**
     * Get the default certificates from the KeyStore
     * @param crypto The Crypto object containing the default alias
     * @return The default certificates
     * @throws WSSecurityException
     */
    private X509Certificate[] getDefaultCerts(
        Crypto crypto
    ) throws WSSecurityException {
        if (crypto == null) {
            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noSigCryptoFile");
        }
        if (crypto.getDefaultX509Identifier() != null) {
            CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
            cryptoType.setAlias(crypto.getDefaultX509Identifier());
            return crypto.getX509Certificates(cryptoType);
        } else {
            throw new WSSecurityException(
                WSSecurityException.ErrorCode.INVALID_SECURITY, "unsupportedKeyInfo"
            );
        }
    }

    /**
     * Verify the WS-Security signature.
     *
     * The functions at first checks if then <code>KeyInfo</code> that is
     * contained in the signature contains standard X509 data. If yes then
     * get the certificate data via the standard <code>KeyInfo</code> methods.
     *
     * Otherwise, if the <code>KeyInfo</code> info does not contain X509 data, check
     * if we can find a <code>wsse:SecurityTokenReference</code> element. If yes, the next
     * step is to check how to get the certificate. Two methods are currently supported
     * here:
     * <ul>
     * <li> A URI reference to a binary security token contained in the <code>wsse:Security
     * </code> header.  If the dereferenced token is
     * of the correct type the contained certificate is extracted.
     * </li>
     * <li> Issuer name an serial number of the certificate. In this case the method
     * looks up the certificate in the keystore via the <code>crypto</code> parameter.
     * </li>
     * </ul>
     *
     * @param elem        the XMLSignature DOM Element.
     * @return the subject principal of the validated X509 certificate (the
     *         authenticated subject). The calling function may use this
     *         principal for further authentication or authorization.
     * @throws WSSecurityException
     */
    private XMLSignature verifyXMLSignature(
        Element elem,
        X509Certificate[] certs,
        PublicKey publicKey,
        byte[] secretKey,
        String signatureMethod,
        final RequestData data,
        WSDocInfo wsDocInfo
    ) throws WSSecurityException {
        LOG.debug("Verify XML Signature");

        //
        // Perform the signature verification and build up a List of elements that the
        // signature refers to
        //
        Key key = null;
        if (certs != null && certs[0] != null) {
            key = certs[0].getPublicKey();
        } else if (publicKey != null) {
            key = publicKey;
        } else {
            key = KeyUtils.prepareSecretKey(signatureMethod, secretKey);
        }

        if (data.isExpandXopInclude()) {
            // Look for xop:Include Nodes and expand them
            List<Element> includeElements =
                XMLUtils.findElements(elem.getFirstChild(), "Include", WSConstants.XOP_NS);
            WSSecurityUtil.inlineAttachments(includeElements, data.getAttachmentCallbackHandler(), true);
        }

        XMLValidateContext context = new DOMValidateContext(key, elem);
        context.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
        context.setProperty("org.apache.jcp.xml.dsig.secureValidation", Boolean.TRUE);
        context.setProperty("org.jcp.xml.dsig.secureValidation", Boolean.TRUE);
        context.setProperty(STRTransform.TRANSFORM_WS_DOC_INFO, wsDocInfo);
        if (data.getSignatureProvider() != null) {
            context.setProperty("org.jcp.xml.dsig.internal.dom.SignatureProvider", data.getSignatureProvider());
        }

        context.setProperty(AttachmentContentSignatureTransform.ATTACHMENT_CALLBACKHANDLER,
                            data.getAttachmentCallbackHandler());

        try {
            XMLSignature xmlSignature = signatureFactory.unmarshalXMLSignature(context);
            checkBSPCompliance(xmlSignature, data.getBSPEnforcer());

            // Check for compliance against the defined AlgorithmSuite
            AlgorithmSuite algorithmSuite = data.getAlgorithmSuite();
            if (algorithmSuite != null) {
                AlgorithmSuiteValidator algorithmSuiteValidator = new
                    AlgorithmSuiteValidator(algorithmSuite);
                algorithmSuiteValidator.checkSignatureAlgorithms(xmlSignature);
            }

            // Test for replay attacks
            testMessageReplay(elem, xmlSignature.getSignatureValue().getValue(), key, data, wsDocInfo);

            setElementsOnContext(xmlSignature, (DOMValidateContext)context, data, wsDocInfo);

            boolean signatureOk = xmlSignature.validate(context);
            if (signatureOk) {
                return xmlSignature;
            }
            //
            // Log the exact signature error
            //
            if (LOG.isDebugEnabled()) {
                LOG.debug("XML Signature verification has failed");
                boolean signatureValidationCheck =
                    xmlSignature.getSignatureValue().validate(context);
                LOG.debug("Signature Validation check: " + signatureValidationCheck);
                java.util.Iterator<?> referenceIterator =
                    xmlSignature.getSignedInfo().getReferences().iterator();
                while (referenceIterator.hasNext()) {
                    Reference reference = (Reference)referenceIterator.next();
                    boolean referenceValidationCheck = reference.validate(context);
                    String id = reference.getId();
                    if (id == null) {
                        id = reference.getURI();
                    }
                    LOG.debug("Reference " + id + " check: " + referenceValidationCheck);
                }
            }
        } catch (WSSecurityException ex) {
            throw ex;
        } catch (Exception ex) {
            throw new WSSecurityException(
                WSSecurityException.ErrorCode.FAILED_CHECK, ex
            );
        }
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
    }

    /**
     * Retrieve the Reference elements and set them on the ValidateContext
     * @param xmlSignature the XMLSignature object to get the references from
     * @param context the ValidateContext
     * @param wsDocInfo the WSDocInfo object where tokens are stored
     * @param doc the owner document from which to find elements
     * @throws WSSecurityException
     */
    private void setElementsOnContext(
        XMLSignature xmlSignature,
        DOMValidateContext context,
        RequestData data,
        WSDocInfo wsDocInfo
    ) throws WSSecurityException {
        java.util.Iterator<?> referenceIterator =
            xmlSignature.getSignedInfo().getReferences().iterator();
        CallbackLookup callbackLookup = wsDocInfo.getCallbackLookup();
        while (referenceIterator.hasNext()) {
            Reference reference = (Reference)referenceIterator.next();
            String uri = reference.getURI();
            Element element = callbackLookup.getAndRegisterElement(uri, null, true, context);
            if (element == null) {
                wsDocInfo.setTokenOnContext(uri, context);
            } else if ("BinarySecurityToken".equals(element.getLocalName())
                && WSConstants.WSSE_NS.equals(element.getNamespaceURI())
                && isXopInclude(element)) {
                // We don't write out the xop:Include bytes into the BinarySecurityToken by default
                // But if the BST is signed, then we have to, or else Signature validation fails...
                handleXopInclude(element, wsDocInfo);
            } else if (data.isExpandXopInclude() && element.getFirstChild() != null) {
                // Look for xop:Include Nodes
                List<Element> includeElements =
                    XMLUtils.findElements(element.getFirstChild(), "Include", WSConstants.XOP_NS);
                for (Element includeElement : includeElements) {
                    String xopURI = includeElement.getAttributeNS(null, "href");
                    if (xopURI != null) {
                        // Store the bytes in the attachment to calculate the signature
                        byte[] attachmentBytes = WSSecurityUtil.getBytesFromAttachment(xopURI, data);
                        String encodedBytes = org.apache.xml.security.utils.XMLUtils.encodeToString(attachmentBytes);

                        Node newCipherValueChild =
                            includeElement.getOwnerDocument().createTextNode(encodedBytes);
                        includeElement.getParentNode().replaceChild(newCipherValueChild, includeElement);
                    }
                }
            }
        }
    }

    private boolean isXopInclude(Element element) {
        Element elementChild =
            XMLUtils.getDirectChildElement(element, "Include", WSConstants.XOP_NS);
        if (elementChild != null && elementChild.hasAttributeNS(null, "href")) {
            String xopUri = elementChild.getAttributeNS(null, "href");
            if (xopUri != null && xopUri.startsWith("cid:")) {
                return true;
            }
        }
        return false;
    }

    private void handleXopInclude(Element element, WSDocInfo wsDocInfo) {
        Map<Integer, List<WSSecurityEngineResult>> actionResults = wsDocInfo.getActionResults();
        if (actionResults != null && actionResults.containsKey(WSConstants.BST)) {
            for (WSSecurityEngineResult result : actionResults.get(WSConstants.BST)) {
                Element token = (Element)result.get(WSSecurityEngineResult.TAG_TOKEN_ELEMENT);
                if (element.equals(token)) {
                    BinarySecurity binarySecurity =
                        (BinarySecurity)result.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
                    binarySecurity.encodeRawToken();
                    return;
                }
            }
        }
    }

    /**
     * Get the signature method algorithm URI from the associated signature element.
     * @param signatureElement The signature element
     * @return the signature method URI
     */
    private static String getSignatureMethod(
        Element signatureElement
    ) {
        Element signedInfoElement =
            XMLUtils.getDirectChildElement(
                signatureElement,
                "SignedInfo",
                WSConstants.SIG_NS
            );
        if (signedInfoElement != null) {
            Element signatureMethodElement =
                XMLUtils.getDirectChildElement(
                    signedInfoElement,
                    "SignatureMethod",
                    WSConstants.SIG_NS
                );
            if (signatureMethodElement != null) {
                return signatureMethodElement.getAttributeNS(null, "Algorithm");
            }
        }
        return null;
    }


    /**
     * This method digs into the Signature element to get the elements that
     * this Signature covers. Build the QName of these Elements and return them
     * to caller
     * @param doc The owning document
     * @param signedInfo The SignedInfo object
     * @param requestData A RequestData instance
     * @return A list of protected references
     * @throws WSSecurityException
     */
    private List<WSDataRef> buildProtectedRefs(
        Document doc,
        SignedInfo signedInfo,
        RequestData requestData,
        WSDocInfo wsDocInfo
    ) throws WSSecurityException {
        List<WSDataRef> protectedRefs = new ArrayList<>(signedInfo.getReferences().size());
        for (Object reference : signedInfo.getReferences()) {
            Reference siRef = (Reference)reference;
            String uri = siRef.getURI();

            if (!"".equals(uri)) {
                Element se = dereferenceSTR(doc, siRef, requestData, wsDocInfo);
                // If an STR Transform is not used then just find the cached element
                boolean attachment = false;
                if (se == null) {
                    Data dereferencedData = siRef.getDereferencedData();
                    if (dereferencedData instanceof NodeSetData) {
                        NodeSetData data = (NodeSetData)dereferencedData;
                        java.util.Iterator<?> iter = data.iterator();

                        while (iter.hasNext()) {
                            Node n = (Node)iter.next();
                            if (n instanceof Element) {
                                se = (Element)n;
                                break;
                            }
                        }
                    } else if (dereferencedData instanceof OctetStreamData) {
                        se = doc.createElementNS("http://docs.oasis-open.org/wss/oasis-wss-SwAProfile-1.1",
                                                 "attachment");
                        attachment = true;
                    }
                }
                if (se == null) {
                    throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
                }

                WSDataRef ref = new WSDataRef();
                ref.setWsuId(uri);
                ref.setProtectedElement(se);
                ref.setAlgorithm(signedInfo.getSignatureMethod().getAlgorithm());
                ref.setDigestAlgorithm(siRef.getDigestMethod().getAlgorithm());
                ref.setDigestValue(siRef.getDigestValue());
                ref.setAttachment(attachment);

                // Set the Transform algorithms as well
                @SuppressWarnings("unchecked")
                List<Transform> transforms = (List<Transform>)siRef.getTransforms();
                List<String> transformAlgorithms = new ArrayList<>(transforms.size());
                for (Transform transform : transforms) {
                    transformAlgorithms.add(transform.getAlgorithm());
                }
                ref.setTransformAlgorithms(transformAlgorithms);

                ref.setXpath(EncryptionUtils.getXPath(se));
                protectedRefs.add(ref);
            }
        }
        return protectedRefs;
    }

    /**
     * Check to see if a SecurityTokenReference transform was used, if so then return the
     * dereferenced element.
     */
    private Element dereferenceSTR(
        Document doc,
        Reference siRef,
        RequestData requestData,
        WSDocInfo wsDocInfo
    ) throws WSSecurityException {

        for (Object transformObject : siRef.getTransforms()) {

            Transform transform = (Transform)transformObject;

            if (STRTransform.TRANSFORM_URI.equals(transform.getAlgorithm())) {
                NodeSetData data = (NodeSetData)siRef.getDereferencedData();
                if (data != null) {
                    java.util.Iterator<?> iter = data.iterator();

                    Node securityTokenReference = null;
                    while (iter.hasNext()) {
                        Node node = (Node)iter.next();
                        if ("SecurityTokenReference".equals(node.getLocalName())) {
                            securityTokenReference = node;
                            break;
                        }
                    }

                    if (securityTokenReference != null) {
                        SecurityTokenReference secTokenRef =
                            new SecurityTokenReference(
                                (Element)securityTokenReference,
                                requestData.getBSPEnforcer()
                            );
                        Element se = STRTransformUtil.dereferenceSTR(doc, secTokenRef, wsDocInfo);
                        if (se != null) {
                            return se;
                        }
                    }
                }
            }
        }
        return null;
    }

    /**
     * Test for a replayed message. The cache key is the Timestamp Created String, the signature
     * value, and the encoded value of the signing key.
     * @param signatureElement
     * @param signatureValue
     * @param key
     * @param requestData
     * @param wsDocInfo
     * @throws WSSecurityException
     */
    private void testMessageReplay(
        Element signatureElement,
        byte[] signatureValue,
        Key key,
        RequestData requestData,
        WSDocInfo wsDocInfo
    ) throws WSSecurityException {
        ReplayCache replayCache = requestData.getTimestampReplayCache();
        if (replayCache == null) {
            return;
        }

        // Find the Timestamp
        List<WSSecurityEngineResult> foundResults = wsDocInfo.getResultsByTag(WSConstants.TS);
        Timestamp timeStamp = null;
        if (foundResults.isEmpty()) {
            // Search for a Timestamp below the Signature
            Node sibling = signatureElement.getNextSibling();
            while (sibling != null) {
                if (sibling instanceof Element
                    && WSConstants.TIMESTAMP_TOKEN_LN.equals(sibling.getLocalName())
                    && WSConstants.WSU_NS.equals(sibling.getNamespaceURI())) {
                    timeStamp = new Timestamp((Element)sibling, requestData.getBSPEnforcer());
                    break;
                }
                sibling = sibling.getNextSibling();
            }
        } else {
            timeStamp = (Timestamp)foundResults.get(0).get(WSSecurityEngineResult.TAG_TIMESTAMP);
        }
        if (timeStamp == null) {
            return;
        }

        // Test for replay attacks
        String identifier = timeStamp.getCreatedString() + "" + Arrays.hashCode(signatureValue)
            + "" + Arrays.hashCode(key.getEncoded());

        if (replayCache.contains(identifier)) {
            throw new WSSecurityException(
                WSSecurityException.ErrorCode.INVALID_SECURITY,
                "invalidTimestamp",
                new Object[] {"A replay attack has been detected"});
        }

        // Store the Timestamp/SignatureValue/Key combination in the cache
        if (timeStamp.getExpires() != null) {
            replayCache.add(identifier, 1L + Duration.between(Instant.now(), timeStamp.getExpires()).getSeconds());
        } else {
            replayCache.add(identifier);
        }

    }

    /**
     * Check BSP compliance (Note some other checks are done elsewhere in this class)
     * @throws WSSecurityException
     */
    private void checkBSPCompliance(
        XMLSignature xmlSignature,
        BSPEnforcer bspEnforcer
    ) throws WSSecurityException {
        // Check for Manifests
        for (Object object : xmlSignature.getObjects()) {
            if (object instanceof XMLObject) {
                XMLObject xmlObject = (XMLObject)object;
                for (Object xmlStructure : xmlObject.getContent()) {
                    if (xmlStructure instanceof Manifest) {
                        bspEnforcer.handleBSPRule(BSPRule.R5403);
                    }
                }
            }
        }

        // Check the c14n algorithm
        String c14nMethod =
            xmlSignature.getSignedInfo().getCanonicalizationMethod().getAlgorithm();
        if (!WSConstants.C14N_EXCL_OMIT_COMMENTS.equals(c14nMethod)) {
            bspEnforcer.handleBSPRule(BSPRule.R5404);
        }

        // Not allowed HMAC OutputLength
        AlgorithmParameterSpec parameterSpec =
            xmlSignature.getSignedInfo().getSignatureMethod().getParameterSpec();
        if (parameterSpec instanceof HMACParameterSpec) {
            bspEnforcer.handleBSPRule(BSPRule.R5401);
        }

        // Must have exclusive C14N without comments
        parameterSpec =
            xmlSignature.getSignedInfo().getCanonicalizationMethod().getParameterSpec();
        if (parameterSpec != null && !(parameterSpec instanceof ExcC14NParameterSpec)) {
            bspEnforcer.handleBSPRule(BSPRule.R5404);
        }

        // Check References
        for (Object refObject : xmlSignature.getSignedInfo().getReferences()) {
            Reference reference = (Reference)refObject;
            if (reference.getTransforms().isEmpty()) {
                bspEnforcer.handleBSPRule(BSPRule.R5416);
            }
            for (int i = 0; i < reference.getTransforms().size(); i++) {
                Transform transform = (Transform)reference.getTransforms().get(i);
                String algorithm = transform.getAlgorithm();
                if (!(WSConstants.C14N_EXCL_OMIT_COMMENTS.equals(algorithm)
                    || STRTransform.TRANSFORM_URI.equals(algorithm)
                    || WSConstants.NS_XMLDSIG_FILTER2.equals(algorithm)
                    || WSConstants.NS_XMLDSIG_ENVELOPED_SIGNATURE.equals(algorithm)
                    || WSConstants.SWA_ATTACHMENT_COMPLETE_SIG_TRANS.equals(algorithm)
                    || WSConstants.SWA_ATTACHMENT_CONTENT_SIG_TRANS.equals(algorithm))) {
                    bspEnforcer.handleBSPRule(BSPRule.R5423);
                }
                if (i == (reference.getTransforms().size() - 1)
                    && !(WSConstants.C14N_EXCL_OMIT_COMMENTS.equals(algorithm)
                        || STRTransform.TRANSFORM_URI.equals(algorithm)
                        || WSConstants.SWA_ATTACHMENT_COMPLETE_SIG_TRANS.equals(algorithm)
                        || WSConstants.SWA_ATTACHMENT_CONTENT_SIG_TRANS.equals(algorithm))) {
                    bspEnforcer.handleBSPRule(BSPRule.R5412);
                }

                if (WSConstants.C14N_EXCL_OMIT_COMMENTS.equals(algorithm)) {
                    parameterSpec = transform.getParameterSpec();
                    if (parameterSpec != null && !(parameterSpec instanceof ExcC14NParameterSpec)) {
                        bspEnforcer.handleBSPRule(BSPRule.R5407);
                    }
                }
            }
        }
    }

}
