All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.wss4j.stax.impl.InboundWSSecurityContextImpl Maven / Gradle / Ivy

There is a newer version: 3.0.4
Show newest version
/**
 * 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.stax.impl;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;

import javax.xml.namespace.QName;

import org.apache.wss4j.common.bsp.BSPRule;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.stax.ext.WSInboundSecurityContext;
import org.apache.wss4j.stax.ext.WSSConstants;
import org.apache.wss4j.stax.securityEvent.HttpsTokenSecurityEvent;
import org.apache.wss4j.stax.securityEvent.WSSecurityEventConstants;
import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
import org.apache.wss4j.stax.utils.WSSUtils;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.stax.impl.InboundSecurityContextImpl;
import org.apache.xml.security.stax.securityEvent.AlgorithmSuiteSecurityEvent;
import org.apache.xml.security.stax.securityEvent.ContentEncryptedElementSecurityEvent;
import org.apache.xml.security.stax.securityEvent.EncryptedElementSecurityEvent;
import org.apache.xml.security.stax.securityEvent.SecurityEvent;
import org.apache.xml.security.stax.securityEvent.SecurityEventConstants;
import org.apache.xml.security.stax.securityEvent.SignedElementSecurityEvent;
import org.apache.xml.security.stax.securityEvent.TokenSecurityEvent;
import org.apache.xml.security.stax.securityToken.InboundSecurityToken;
import org.apache.xml.security.stax.securityToken.SecurityToken;
import org.apache.xml.security.stax.securityToken.SecurityTokenConstants;

/**
 * Concrete security context implementation
 */
public class InboundWSSecurityContextImpl extends InboundSecurityContextImpl implements WSInboundSecurityContext {

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

    private final Deque securityEventQueue = new ArrayDeque();
    private boolean operationSecurityEventOccured = false;
    private boolean messageEncryptionTokenOccured = false;
    private boolean allowRSA15KeyTransportAlgorithm = false;
    private boolean disableBSPEnforcement;

    private List ignoredBSPRules = Collections.emptyList();

    @Override
    public synchronized void registerSecurityEvent(SecurityEvent securityEvent) throws XMLSecurityException {

        if (WSSecurityEventConstants.AlgorithmSuite.equals(securityEvent.getSecurityEventType())) {
            //do not cache AlgorithmSuite securityEvents and forward them directly to allow
            //the user to check them before they are used internally.
            forwardSecurityEvent(securityEvent);
            return;
        }

        if (operationSecurityEventOccured) {
            if (!this.messageEncryptionTokenOccured
                    && securityEvent instanceof TokenSecurityEvent) {
                @SuppressWarnings("unchecked")
                TokenSecurityEvent tokenSecurityEvent =
                        ((TokenSecurityEvent) securityEvent);

                if (tokenSecurityEvent.getSecurityToken().getTokenUsages().contains(WSSecurityTokenConstants.TokenUsage_Encryption)) {
                    InboundSecurityToken securityToken = WSSUtils.getRootToken(tokenSecurityEvent.getSecurityToken());

                    TokenSecurityEvent newTokenSecurityEvent =
                            WSSUtils.createTokenSecurityEvent(securityToken, tokenSecurityEvent.getCorrelationID());
                    setTokenUsage(newTokenSecurityEvent, WSSecurityTokenConstants.TOKENUSAGE_MAIN_ENCRYPTION);
                    securityEvent = newTokenSecurityEvent;
                    this.messageEncryptionTokenOccured = true;
                }
            }

            forwardSecurityEvent(securityEvent);
            return;
        }

        if (WSSecurityEventConstants.OPERATION.equals(securityEvent.getSecurityEventType())) {
            operationSecurityEventOccured = true;

            identifySecurityTokenDependenciesAndUsage(securityEventQueue);

            Iterator securityEventIterator = securityEventQueue.descendingIterator();
            while (securityEventIterator.hasNext()) {
                SecurityEvent prevSecurityEvent = securityEventIterator.next();
                forwardSecurityEvent(prevSecurityEvent);
            }
            //forward operation security event
            forwardSecurityEvent(securityEvent);

            securityEventQueue.clear();
            return;
        }

        securityEventQueue.push(securityEvent);
    }

    @Override
    protected void forwardSecurityEvent(SecurityEvent securityEvent) throws XMLSecurityException {

        if (!allowRSA15KeyTransportAlgorithm && SecurityEventConstants.AlgorithmSuite.equals(securityEvent.getSecurityEventType())) {
            AlgorithmSuiteSecurityEvent algorithmSuiteSecurityEvent = (AlgorithmSuiteSecurityEvent)securityEvent;
            Boolean allowRSA15 = get(WSSConstants.PROP_ALLOW_RSA15_KEYTRANSPORT_ALGORITHM);
            if ((allowRSA15 == null || !allowRSA15) 
                && WSSConstants.NS_XENC_RSA15.equals(algorithmSuiteSecurityEvent.getAlgorithmURI())) {
                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, 
                                              WSSConstants.PROP_ALLOW_RSA15_KEYTRANSPORT_ALGORITHM);
            }
        }

        try {
            super.forwardSecurityEvent(securityEvent);
        } catch (WSSecurityException e) {
            throw e;
        } catch (XMLSecurityException e) {
            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
        }
    }

    private void identifySecurityTokenDependenciesAndUsage(
            Deque securityEventDeque) throws XMLSecurityException {

        MessageTokens messageTokens = new MessageTokens();
        HttpsTokenSecurityEvent httpsTokenSecurityEvent = null;

        List> tokenSecurityEvents = new ArrayList<>();
        Iterator securityEventIterator = securityEventDeque.iterator();
        while (securityEventIterator.hasNext()) {
            SecurityEvent securityEvent = securityEventIterator.next();
            if (securityEvent instanceof TokenSecurityEvent) {
                @SuppressWarnings("unchecked")
                TokenSecurityEvent tokenSecurityEvent =
                        (TokenSecurityEvent)securityEvent;

                if (WSSecurityEventConstants.HTTPS_TOKEN.equals(securityEvent.getSecurityEventType())) {
                    HttpsTokenSecurityEvent actHttpsTokenSecurityEvent = (HttpsTokenSecurityEvent) tokenSecurityEvent;
                    actHttpsTokenSecurityEvent.getSecurityToken().getTokenUsages().clear();
                    actHttpsTokenSecurityEvent.getSecurityToken().addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE);
                    messageTokens.messageSignatureTokens = 
                        addTokenSecurityEvent(actHttpsTokenSecurityEvent, messageTokens.messageSignatureTokens);
                    HttpsTokenSecurityEvent clonedHttpsTokenSecurityEvent = new HttpsTokenSecurityEvent();
                    clonedHttpsTokenSecurityEvent.setAuthenticationType(actHttpsTokenSecurityEvent.getAuthenticationType());
                    clonedHttpsTokenSecurityEvent.setIssuerName(actHttpsTokenSecurityEvent.getIssuerName());
                    clonedHttpsTokenSecurityEvent.setSecurityToken(actHttpsTokenSecurityEvent.getSecurityToken());
                    clonedHttpsTokenSecurityEvent.getSecurityToken().addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_ENCRYPTION);
                    messageTokens.messageEncryptionTokens = 
                        addTokenSecurityEvent(actHttpsTokenSecurityEvent, messageTokens.messageEncryptionTokens);
                    httpsTokenSecurityEvent = clonedHttpsTokenSecurityEvent;
                    continue;
                }
                tokenSecurityEvents.add(tokenSecurityEvent);
            }
        }

        //search the root tokens and create new TokenSecurityEvents if not already there...
        for (int i = 0; i < tokenSecurityEvents.size(); i++) {
            TokenSecurityEvent tokenSecurityEvent = tokenSecurityEvents.get(i);
            InboundSecurityToken securityToken = WSSUtils.getRootToken(tokenSecurityEvent.getSecurityToken());

            if (!containsSecurityToken(messageTokens.supportingTokens, securityToken)) {
                TokenSecurityEvent newTokenSecurityEvent =
                        WSSUtils.createTokenSecurityEvent(securityToken, tokenSecurityEvent.getCorrelationID());
                messageTokens.supportingTokens = addTokenSecurityEvent(newTokenSecurityEvent, messageTokens.supportingTokens);
                securityEventDeque.offer(newTokenSecurityEvent);
            }
            //remove old TokenSecurityEvent so that only root tokens are in the queue
            securityEventDeque.remove(tokenSecurityEvent);
        }

        parseSupportingTokens(messageTokens, httpsTokenSecurityEvent, securityEventDeque);

        if (messageTokens.messageSignatureTokens.isEmpty()) {
            InboundSecurityToken messageSignatureToken = getSupportingTokenSigningToken(messageTokens, securityEventDeque);

            TokenSecurityEvent tokenSecurityEvent =
                    getTokenSecurityEvent(messageSignatureToken, tokenSecurityEvents);
            if (tokenSecurityEvent != null) {
                removeTokenSecurityEvent(tokenSecurityEvent, messageTokens.supportingTokens);
                removeTokenSecurityEvent(tokenSecurityEvent, messageTokens.signedSupportingTokens);
                removeTokenSecurityEvent(tokenSecurityEvent, messageTokens.endorsingSupportingTokens);
                removeTokenSecurityEvent(tokenSecurityEvent, messageTokens.signedEndorsingSupportingTokens);
                removeTokenSecurityEvent(tokenSecurityEvent, messageTokens.signedEncryptedSupportingTokens);
                removeTokenSecurityEvent(tokenSecurityEvent, messageTokens.encryptedSupportingTokens);
                removeTokenSecurityEvent(tokenSecurityEvent, messageTokens.endorsingEncryptedSupportingTokens);
                removeTokenSecurityEvent(tokenSecurityEvent, messageTokens.signedEndorsingEncryptedSupportingTokens);
                messageTokens.messageSignatureTokens = addTokenSecurityEvent(tokenSecurityEvent, messageTokens.messageSignatureTokens);
            }
        }

        if (messageTokens.messageSignatureTokens.isEmpty()) {
            for (Iterator> iterator = 
                messageTokens.supportingTokens.iterator(); iterator.hasNext();) {
                TokenSecurityEvent supportingToken = iterator.next();
                if (supportingToken.getSecurityToken().getTokenUsages().contains(WSSecurityTokenConstants.TokenUsage_Signature)) {
                    iterator.remove();
                    messageTokens.messageSignatureTokens = addTokenSecurityEvent(supportingToken, messageTokens.messageSignatureTokens);
                    break;
                }
            }
        }

        if (messageTokens.messageEncryptionTokens.isEmpty()) {
            for (Iterator> iterator = 
                messageTokens.supportingTokens.iterator(); iterator.hasNext();) {
                TokenSecurityEvent supportingToken = iterator.next();
                if (supportingToken.getSecurityToken().getTokenUsages().contains(WSSecurityTokenConstants.TokenUsage_Encryption)) {
                    iterator.remove();
                    messageTokens.messageEncryptionTokens = addTokenSecurityEvent(supportingToken, messageTokens.messageEncryptionTokens);
                    break;
                }
            }
        }

        if (!messageTokens.messageEncryptionTokens.isEmpty()) {
            this.messageEncryptionTokenOccured = true;
        }

        setTokenUsage(messageTokens.messageSignatureTokens, WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE);
        setTokenUsage(messageTokens.messageEncryptionTokens, WSSecurityTokenConstants.TOKENUSAGE_MAIN_ENCRYPTION);
        setTokenUsage(messageTokens.supportingTokens, WSSecurityTokenConstants.TOKENUSAGE_SUPPORTING_TOKENS);
        setTokenUsage(messageTokens.signedSupportingTokens, WSSecurityTokenConstants.TOKENUSAGE_SIGNED_SUPPORTING_TOKENS);
        setTokenUsage(messageTokens.endorsingSupportingTokens, 
                      WSSecurityTokenConstants.TOKENUSAGE_ENDORSING_SUPPORTING_TOKENS);
        setTokenUsage(messageTokens.signedEndorsingSupportingTokens, 
                      WSSecurityTokenConstants.TOKENUSAGE_SIGNED_ENDORSING_SUPPORTING_TOKENS);
        setTokenUsage(messageTokens.signedEncryptedSupportingTokens, 
                      WSSecurityTokenConstants.TOKENUSAGE_SIGNED_ENCRYPTED_SUPPORTING_TOKENS);
        setTokenUsage(messageTokens.encryptedSupportingTokens, 
                      WSSecurityTokenConstants.TOKENUSAGE_ENCRYPTED_SUPPORTING_TOKENS);
        setTokenUsage(messageTokens.endorsingEncryptedSupportingTokens, 
                      WSSecurityTokenConstants.TOKENUSAGE_ENDORSING_ENCRYPTED_SUPPORTING_TOKENS);
        setTokenUsage(messageTokens.signedEndorsingEncryptedSupportingTokens, 
                      WSSecurityTokenConstants.TOKENUSAGE_SIGNED_ENDORSING_ENCRYPTED_SUPPORTING_TOKENS);
    }
    
    private void parseSupportingTokens(MessageTokens messageTokens, HttpsTokenSecurityEvent httpsTokenSecurityEvent,
                                       Deque securityEventDeque) throws XMLSecurityException {
        Iterator> supportingTokensIterator = messageTokens.supportingTokens.iterator();
        while (supportingTokensIterator.hasNext()) {
            TokenSecurityEvent tokenSecurityEvent = supportingTokensIterator.next();
            List signingSecurityTokens = 
                isSignedToken(tokenSecurityEvent, securityEventDeque, httpsTokenSecurityEvent);

            List signatureElementPath = new ArrayList<>(4);
            signatureElementPath.addAll(WSSConstants.WSSE_SECURITY_HEADER_PATH);
            signatureElementPath.add(WSSConstants.TAG_dsig_Signature);
            boolean signsSignature = signsElement(tokenSecurityEvent, signatureElementPath, securityEventDeque);
            boolean encryptsSignature = encryptsElement(tokenSecurityEvent, signatureElementPath, securityEventDeque);

            List signatureConfirmationElementPath = new ArrayList<>(4);
            signatureConfirmationElementPath.addAll(WSSConstants.WSSE_SECURITY_HEADER_PATH);
            signatureConfirmationElementPath.add(WSSConstants.TAG_WSSE11_SIG_CONF);
            boolean signsSignatureConfirmation = 
                signsElement(tokenSecurityEvent, signatureConfirmationElementPath, securityEventDeque);
            boolean encryptsSignatureConfirmation = 
                encryptsElement(tokenSecurityEvent, signatureConfirmationElementPath, securityEventDeque);

            List timestampElementPath = new ArrayList<>(4);
            timestampElementPath.addAll(WSSConstants.WSSE_SECURITY_HEADER_PATH);
            timestampElementPath.add(WSSConstants.TAG_WSU_TIMESTAMP);
            boolean signsTimestamp = signsElement(tokenSecurityEvent, timestampElementPath, securityEventDeque);

            List usernameTokenElementPath = new ArrayList<>(4);
            usernameTokenElementPath.addAll(WSSConstants.WSSE_SECURITY_HEADER_PATH);
            usernameTokenElementPath.add(WSSConstants.TAG_WSSE_USERNAME_TOKEN);
            boolean encryptsUsernameToken = encryptsElement(tokenSecurityEvent, usernameTokenElementPath, securityEventDeque);

            boolean transportSecurityActive = Boolean.TRUE.equals(get(WSSConstants.TRANSPORT_SECURITY_ACTIVE));

            List encryptingSecurityTokens = 
                isEncryptedToken(tokenSecurityEvent, securityEventDeque, httpsTokenSecurityEvent);

            boolean signatureUsage = 
                tokenSecurityEvent.getSecurityToken().getTokenUsages().contains(WSSecurityTokenConstants.TokenUsage_Signature);
            boolean encryptionUsage = 
                tokenSecurityEvent.getSecurityToken().getTokenUsages().contains(WSSecurityTokenConstants.TokenUsage_Encryption);

            if (!transportSecurityActive && signsSignatureConfirmation && signsTimestamp && !signsSignature) {
                supportingTokensIterator.remove();
                messageTokens.messageSignatureTokens = 
                    addTokenSecurityEvent(tokenSecurityEvent, messageTokens.messageSignatureTokens);
                if (encryptionUsage) {
                    messageTokens.messageEncryptionTokens = 
                        addTokenSecurityEvent(tokenSecurityEvent, messageTokens.messageEncryptionTokens);
                }
            } else if (!transportSecurityActive && signsSignatureConfirmation && !signsSignature) {
                supportingTokensIterator.remove();
                messageTokens.messageSignatureTokens = 
                    addTokenSecurityEvent(tokenSecurityEvent, messageTokens.messageSignatureTokens);
                if (encryptionUsage) {
                    messageTokens.messageEncryptionTokens = 
                        addTokenSecurityEvent(tokenSecurityEvent, messageTokens.messageEncryptionTokens);
                }
            } else if (!transportSecurityActive && signsTimestamp && !signsSignature) {
                supportingTokensIterator.remove();
                messageTokens.messageSignatureTokens = 
                    addTokenSecurityEvent(tokenSecurityEvent, messageTokens.messageSignatureTokens);
                if (encryptionUsage) {
                    messageTokens.messageEncryptionTokens = 
                        addTokenSecurityEvent(tokenSecurityEvent, messageTokens.messageEncryptionTokens);
                }
            } else if (!transportSecurityActive 
                && (encryptsSignature || encryptsSignatureConfirmation || encryptsUsernameToken)) {
                supportingTokensIterator.remove();
                messageTokens.messageEncryptionTokens = 
                    addTokenSecurityEvent(tokenSecurityEvent, messageTokens.messageEncryptionTokens);
            } else if (signsSignature && signingSecurityTokens.size() > 0 && encryptingSecurityTokens.size() > 0) {
                supportingTokensIterator.remove();
                messageTokens.signedEndorsingEncryptedSupportingTokens = 
                    addTokenSecurityEvent(tokenSecurityEvent, messageTokens.signedEndorsingEncryptedSupportingTokens);
            } else if (transportSecurityActive && signsTimestamp && signingSecurityTokens.size() > 0 
                && encryptingSecurityTokens.size() > 0) {
                supportingTokensIterator.remove();
                messageTokens.signedEndorsingEncryptedSupportingTokens = 
                    addTokenSecurityEvent(tokenSecurityEvent, messageTokens.signedEndorsingEncryptedSupportingTokens);
            } else if (signsSignature && signingSecurityTokens.size() == 0 && encryptingSecurityTokens.size() > 0) {
                supportingTokensIterator.remove();
                messageTokens.endorsingEncryptedSupportingTokens = 
                    addTokenSecurityEvent(tokenSecurityEvent, messageTokens.endorsingEncryptedSupportingTokens);
            } else if (signsSignature && signingSecurityTokens.size() > 0) {
                supportingTokensIterator.remove();
                messageTokens.signedEndorsingSupportingTokens = 
                    addTokenSecurityEvent(tokenSecurityEvent, messageTokens.signedEndorsingSupportingTokens);
            } else if (signatureUsage && signingSecurityTokens.size() > 0) {
                supportingTokensIterator.remove();
                messageTokens.signedEndorsingSupportingTokens = 
                    addTokenSecurityEvent(tokenSecurityEvent, messageTokens.signedEndorsingSupportingTokens);
            } else if (signsSignature) {
                supportingTokensIterator.remove();
                messageTokens.endorsingSupportingTokens = 
                    addTokenSecurityEvent(tokenSecurityEvent, messageTokens.endorsingSupportingTokens);
            } else if (signingSecurityTokens.size() > 0 && encryptingSecurityTokens.size() > 0) {
                supportingTokensIterator.remove();
                messageTokens.signedEncryptedSupportingTokens = 
                    addTokenSecurityEvent(tokenSecurityEvent, messageTokens.signedEncryptedSupportingTokens);
            } else if (signingSecurityTokens.size() > 0) {
                supportingTokensIterator.remove();
                messageTokens.signedSupportingTokens = 
                    addTokenSecurityEvent(tokenSecurityEvent, messageTokens.signedSupportingTokens);
            } else if (encryptingSecurityTokens.size() > 0) {
                supportingTokensIterator.remove();
                messageTokens.encryptedSupportingTokens = 
                    addTokenSecurityEvent(tokenSecurityEvent, messageTokens.encryptedSupportingTokens);
            }
        }
    }

    private void removeTokenSecurityEvent(TokenSecurityEvent tokenSecurityEvent,
                                          List> tokenSecurityEventList) {
        for (int i = 0; i < tokenSecurityEventList.size(); i++) {
            TokenSecurityEvent securityEvent = tokenSecurityEventList.get(i);
            if (securityEvent.getSecurityToken().getId().equals(tokenSecurityEvent.getSecurityToken().getId())) {
                tokenSecurityEventList.remove(securityEvent);
                return;
            }
        }
    }

    private List> addTokenSecurityEvent(
            TokenSecurityEvent tokenSecurityEvent,
            List> tokenSecurityEventList) {
        if (tokenSecurityEventList == Collections.>emptyList()) {
            tokenSecurityEventList = new ArrayList<>();
        }
        tokenSecurityEventList.add(tokenSecurityEvent);
        return tokenSecurityEventList;
    }

    private boolean containsSecurityToken(List> supportingTokens, 
                                          SecurityToken securityToken) {
        if (securityToken != null) {
            for (int i = 0; i < supportingTokens.size(); i++) {
                TokenSecurityEvent tokenSecurityEvent = supportingTokens.get(i);
                if (tokenSecurityEvent.getSecurityToken().getId().equals(securityToken.getId())) {
                    return true;
                }
            }
        }
        return false;
    }

    private TokenSecurityEvent getTokenSecurityEvent(
            InboundSecurityToken securityToken,
            List> tokenSecurityEvents) throws XMLSecurityException {
        if (securityToken != null) {
            for (int i = 0; i < tokenSecurityEvents.size(); i++) {
                TokenSecurityEvent tokenSecurityEvent = tokenSecurityEvents.get(i);
                if (tokenSecurityEvent.getSecurityToken().getId().equals(securityToken.getId())) {
                    return tokenSecurityEvent;
                }
            }
        }
        return null;
    }

    private InboundSecurityToken getSupportingTokenSigningToken(
            MessageTokens messageTokens,
            Deque securityEventDeque
    ) throws XMLSecurityException {

        //todo we have to check if the signingTokens also cover the other supporting tokens!
        for (int i = 0; i < messageTokens.signedSupportingTokens.size(); i++) {
            TokenSecurityEvent tokenSecurityEvent = messageTokens.signedSupportingTokens.get(i);
            List signingSecurityTokens = getSigningToken(tokenSecurityEvent, securityEventDeque);
            if (signingSecurityTokens.size() == 1) {
                return signingSecurityTokens.get(0);
            }
        }
        for (int i = 0; i < messageTokens.signedEndorsingSupportingTokens.size(); i++) {
            TokenSecurityEvent tokenSecurityEvent = messageTokens.signedEndorsingSupportingTokens.get(i);
            List signingSecurityTokens = getSigningToken(tokenSecurityEvent, securityEventDeque);
            if (signingSecurityTokens.size() == 1) {
                return signingSecurityTokens.get(0);
            }
        }
        for (int i = 0; i < messageTokens.signedEncryptedSupportingTokens.size(); i++) {
            TokenSecurityEvent tokenSecurityEvent = messageTokens.signedEncryptedSupportingTokens.get(i);
            List signingSecurityTokens = getSigningToken(tokenSecurityEvent, securityEventDeque);
            if (signingSecurityTokens.size() == 1) {
                return signingSecurityTokens.get(0);
            }
        }
        for (int i = 0; i < messageTokens.signedEndorsingEncryptedSupportingTokens.size(); i++) {
            TokenSecurityEvent tokenSecurityEvent = messageTokens.signedEndorsingEncryptedSupportingTokens.get(i);
            List signingSecurityTokens = getSigningToken(tokenSecurityEvent, securityEventDeque);
            if (signingSecurityTokens.size() == 1) {
                return signingSecurityTokens.get(0);
            }
        }
        return null;
    }

    private List getSigningToken(TokenSecurityEvent tokenSecurityEvent, 
                                                       Deque securityEventDeque) throws XMLSecurityException {
        List signingSecurityTokens = new ArrayList<>();

        for (Iterator iterator = securityEventDeque.iterator(); iterator.hasNext();) {
            SecurityEvent securityEvent = iterator.next();
            if (WSSecurityEventConstants.SignedElement.equals(securityEvent.getSecurityEventType())) {
                SignedElementSecurityEvent signedElementSecurityEvent = (SignedElementSecurityEvent) securityEvent;
                if (signedElementSecurityEvent.isSigned()
                        && WSSUtils.pathMatches(
                        signedElementSecurityEvent.getElementPath(),
                        ((InboundSecurityToken)tokenSecurityEvent.getSecurityToken()).getElementPath(), true, false)
                        ) {
                    signingSecurityTokens.add((InboundSecurityToken)signedElementSecurityEvent.getSecurityToken());
                }
            }
        }
        return signingSecurityTokens;
    }

    private void setTokenUsage(List> tokenSecurityEvents, 
                               WSSecurityTokenConstants.TokenUsage tokenUsage) throws XMLSecurityException {
        for (int i = 0; i < tokenSecurityEvents.size(); i++) {
            TokenSecurityEvent tokenSecurityEvent = tokenSecurityEvents.get(i);
            setTokenUsage(tokenSecurityEvent, tokenUsage);
        }
    }

    private void setTokenUsage(TokenSecurityEvent tokenSecurityEvent, 
                               WSSecurityTokenConstants.TokenUsage tokenUsage) throws XMLSecurityException {
        tokenSecurityEvent.getSecurityToken().getTokenUsages().remove(WSSecurityTokenConstants.TOKENUSAGE_SUPPORTING_TOKENS);
        tokenSecurityEvent.getSecurityToken().getTokenUsages().remove(WSSecurityTokenConstants.TokenUsage_Signature);
        tokenSecurityEvent.getSecurityToken().getTokenUsages().remove(WSSecurityTokenConstants.TokenUsage_Encryption);
        tokenSecurityEvent.getSecurityToken().addTokenUsage(tokenUsage);
    }

    private List isSignedToken(TokenSecurityEvent tokenSecurityEvent,
                                              Deque securityEventDeque,
                                              HttpsTokenSecurityEvent httpsTokenSecurityEvent) throws XMLSecurityException {
        List securityTokenList = new ArrayList<>();
        if (httpsTokenSecurityEvent != null) {
            securityTokenList.add(httpsTokenSecurityEvent.getSecurityToken());
            return securityTokenList;
        }
        for (Iterator iterator = securityEventDeque.iterator(); iterator.hasNext();) {
            SecurityEvent securityEvent = iterator.next();
            if (WSSecurityEventConstants.SignedElement.equals(securityEvent.getSecurityEventType())) {
                SignedElementSecurityEvent signedElementSecurityEvent = (SignedElementSecurityEvent) securityEvent;
                if (signedElementSecurityEvent.isSigned()
                        && tokenSecurityEvent.getSecurityToken() != null
                        && signedElementSecurityEvent.getXmlSecEvent() != null
                        && signedElementSecurityEvent.getXmlSecEvent() 
                            == ((InboundSecurityToken)tokenSecurityEvent.getSecurityToken()).getXMLSecEvent()
                        && !securityTokenList.contains((InboundSecurityToken)signedElementSecurityEvent.getSecurityToken())) {
                    securityTokenList.add((InboundSecurityToken)signedElementSecurityEvent.getSecurityToken());
                }
            }
        }
        return securityTokenList;
    }

    private List isEncryptedToken(TokenSecurityEvent tokenSecurityEvent,
                                                 Deque securityEventDeque,
                                                 HttpsTokenSecurityEvent httpsTokenSecurityEvent) throws XMLSecurityException {

        List securityTokenList = new ArrayList<>();
        if (httpsTokenSecurityEvent != null) {
            securityTokenList.add(httpsTokenSecurityEvent.getSecurityToken());
            return securityTokenList;
        }
        for (Iterator iterator = securityEventDeque.iterator(); iterator.hasNext();) {
            SecurityEvent securityEvent = iterator.next();
            if (WSSecurityEventConstants.EncryptedElement.equals(securityEvent.getSecurityEventType())) {
                EncryptedElementSecurityEvent encryptedElementSecurityEvent = (EncryptedElementSecurityEvent) securityEvent;
                if (encryptedElementSecurityEvent.isEncrypted()
                        && tokenSecurityEvent.getSecurityToken() != null
                        && encryptedElementSecurityEvent.getXmlSecEvent() != null
                        && encryptedElementSecurityEvent.getXmlSecEvent() 
                            == ((InboundSecurityToken)tokenSecurityEvent.getSecurityToken()).getXMLSecEvent()
                        && !securityTokenList.contains((InboundSecurityToken)encryptedElementSecurityEvent.getSecurityToken())) {
                    securityTokenList.add((InboundSecurityToken)encryptedElementSecurityEvent.getSecurityToken());
                }
            }
        }
        return securityTokenList;
    }

    private boolean signsElement(TokenSecurityEvent tokenSecurityEvent, List elementPath,
                                 Deque securityEventDeque) throws XMLSecurityException {
        for (Iterator iterator = securityEventDeque.iterator(); iterator.hasNext();) {
            SecurityEvent securityEvent = iterator.next();
            if (WSSecurityEventConstants.SignedElement.equals(securityEvent.getSecurityEventType())) {
                SignedElementSecurityEvent signedElementSecurityEvent = (SignedElementSecurityEvent) securityEvent;
                if (signedElementSecurityEvent.isSigned()
                        && matchesTokenOrWrappedTokenId(tokenSecurityEvent.getSecurityToken(),
                        signedElementSecurityEvent.getSecurityToken().getId(),
                        SecurityTokenConstants.TokenUsage_Signature)
                        && WSSUtils.pathMatches(elementPath, signedElementSecurityEvent.getElementPath(), true, false)) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean matchesTokenOrWrappedTokenId(
            SecurityToken securityToken, String id,
            SecurityTokenConstants.TokenUsage tokenUsage) throws XMLSecurityException {
        if (securityToken.getId().equals(id) && securityToken.getTokenUsages().contains(tokenUsage)) {
            return true;
        }
        List wrappedTokens = securityToken.getWrappedTokens();
        for (int i = 0; i < wrappedTokens.size(); i++) {
            boolean match = matchesTokenOrWrappedTokenId(wrappedTokens.get(i), id, tokenUsage);
            if (match) {
                return match;
            }
        }
        return false;
    }

    private boolean encryptsElement(TokenSecurityEvent tokenSecurityEvent, List elementPath,
                                    Deque securityEventDeque) throws XMLSecurityException {
        for (Iterator iterator = securityEventDeque.iterator(); iterator.hasNext();) {
            SecurityEvent securityEvent = iterator.next();
            if (WSSecurityEventConstants.EncryptedElement.equals(securityEvent.getSecurityEventType())) {
                EncryptedElementSecurityEvent encryptedElementSecurityEvent = (EncryptedElementSecurityEvent) securityEvent;
                if (encryptedElementSecurityEvent.isEncrypted()
                        && encryptedElementSecurityEvent.getSecurityToken().getId().equals(tokenSecurityEvent.getSecurityToken().getId())
                        && WSSUtils.pathMatches(elementPath, encryptedElementSecurityEvent.getElementPath(), true, false)) {
                    return true;
                }
            } else if (WSSecurityEventConstants.ContentEncrypted.equals(securityEvent.getSecurityEventType())) {
                ContentEncryptedElementSecurityEvent contentEncryptedElementSecurityEvent = 
                    (ContentEncryptedElementSecurityEvent) securityEvent;
                String tokenId = tokenSecurityEvent.getSecurityToken().getId();
                if (contentEncryptedElementSecurityEvent.isEncrypted()
                        && contentEncryptedElementSecurityEvent.getSecurityToken().getId().equals(tokenId)
                        && contentEncryptedElementSecurityEvent.getXmlSecEvent() 
                            == ((InboundSecurityToken)tokenSecurityEvent.getSecurityToken()).getXMLSecEvent()
                        && WSSUtils.pathMatches(elementPath, contentEncryptedElementSecurityEvent.getElementPath(), true, false)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void handleBSPRule(BSPRule bspRule) throws WSSecurityException {
        if (disableBSPEnforcement) {
            return;
        }
        if (!ignoredBSPRules.contains(bspRule)) {
            throw new WSSecurityException(
                    WSSecurityException.ErrorCode.INVALID_SECURITY,
                    "empty",
                    new Object[] {"BSP:" + bspRule.name() + ": " + bspRule.getMsg()});
        } else {
            LOG.warn("BSP:" + bspRule.name() + ": " + bspRule.getMsg());
        }
    }

    @Override
    public void ignoredBSPRules(List bspRules) {
        ignoredBSPRules = new ArrayList<>(bspRules);
    }

    public boolean isDisableBSPEnforcement() {
        return disableBSPEnforcement;
    }

    public void setDisableBSPEnforcement(boolean disableBSPEnforcement) {
        this.disableBSPEnforcement = disableBSPEnforcement;
    }

    public boolean isAllowRSA15KeyTransportAlgorithm() {
        return allowRSA15KeyTransportAlgorithm;
    }

    public void setAllowRSA15KeyTransportAlgorithm(boolean allowRSA15KeyTransportAlgorithm) {
        this.allowRSA15KeyTransportAlgorithm = allowRSA15KeyTransportAlgorithm;
    }
    
    private static class MessageTokens {
        List> messageSignatureTokens = Collections.emptyList();
        List> messageEncryptionTokens = Collections.emptyList();
        List> supportingTokens = Collections.emptyList();
        List> signedSupportingTokens = Collections.emptyList();
        List> endorsingSupportingTokens = Collections.emptyList();
        List> signedEndorsingSupportingTokens = Collections.emptyList();
        List> signedEncryptedSupportingTokens = Collections.emptyList();
        List> encryptedSupportingTokens = Collections.emptyList();
        List> endorsingEncryptedSupportingTokens = Collections.emptyList();
        List> signedEndorsingEncryptedSupportingTokens = Collections.emptyList();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy