public List handleToken()

in ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java [116:269]


    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 && certs.length > 0)) && 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 (tokenId.length() != 0) {
            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);
    }