Package org.apache.wss4j.stax.impl.processor.input

Source Code of org.apache.wss4j.stax.impl.processor.input.DerivedKeyTokenInputHandler

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

import org.apache.wss4j.binding.wssc.AbstractDerivedKeyTokenType;
import org.apache.wss4j.common.derivedKey.DerivedKeyUtils;
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.ext.WSSSecurityProperties;
import org.apache.wss4j.stax.securityToken.UsernameSecurityToken;
import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
import org.apache.wss4j.stax.impl.securityToken.SecurityTokenFactoryImpl;
import org.apache.wss4j.stax.securityEvent.DerivedKeyTokenSecurityEvent;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.stax.config.JCEAlgorithmMapper;
import org.apache.xml.security.stax.ext.AbstractInputSecurityHeaderHandler;
import org.apache.xml.security.stax.ext.InputProcessorChain;
import org.apache.xml.security.stax.ext.XMLSecurityConstants;
import org.apache.xml.security.stax.ext.XMLSecurityProperties;
import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
import org.apache.xml.security.stax.impl.securityToken.AbstractInboundSecurityToken;
import org.apache.xml.security.stax.impl.util.IDGenerator;
import org.apache.xml.security.stax.securityEvent.AlgorithmSuiteSecurityEvent;
import org.apache.xml.security.stax.securityToken.InboundSecurityToken;
import org.apache.xml.security.stax.securityToken.SecurityTokenProvider;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
import java.security.Key;
import java.util.Deque;
import java.util.List;

/**
* Processor for the SecurityContextToken XML Structure
*/
public class DerivedKeyTokenInputHandler extends AbstractInputSecurityHeaderHandler {

    @Override
    public void handle(final InputProcessorChain inputProcessorChain, final XMLSecurityProperties securityProperties,
                       Deque<XMLSecEvent> eventQueue, Integer index) throws XMLSecurityException {

        @SuppressWarnings("unchecked")
        final AbstractDerivedKeyTokenType derivedKeyTokenType =
                ((JAXBElement<AbstractDerivedKeyTokenType>) parseStructure(eventQueue, index, securityProperties)).getValue();
        if (derivedKeyTokenType.getId() == null) {
            derivedKeyTokenType.setId(IDGenerator.generateID(null));
        }
        if (derivedKeyTokenType.getSecurityTokenReference() == null) {
            throw new WSSecurityException(WSSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, "noReference");
        }

        final List<QName> elementPath = getElementPath(eventQueue);
        final XMLSecEvent responsibleXMLSecStartXMLEvent = getResponsibleStartXMLEvent(eventQueue, index);

        SecurityTokenProvider<InboundSecurityToken> securityTokenProvider = new SecurityTokenProvider<InboundSecurityToken>() {

            private AbstractInboundSecurityToken derivedKeySecurityToken = null;

            @Override
            public InboundSecurityToken getSecurityToken() throws XMLSecurityException {

                if (this.derivedKeySecurityToken != null) {
                    return this.derivedKeySecurityToken;
                }

                //todo implement interface to access all derivedKeys? The same would be needed in UserNameToken
                this.derivedKeySecurityToken = new AbstractInboundSecurityToken(
                        (WSInboundSecurityContext) inputProcessorChain.getSecurityContext(),
                        derivedKeyTokenType.getId(), WSSecurityTokenConstants.KeyIdentifier_SecurityTokenDirectReference,
                        true) {

                    private InboundSecurityToken referencedSecurityToken = null;

                    private InboundSecurityToken getReferencedSecurityToken() throws XMLSecurityException {
                        if (this.referencedSecurityToken != null) {
                            return referencedSecurityToken;
                        }

                        this.referencedSecurityToken = SecurityTokenFactoryImpl.getSecurityToken(
                                derivedKeyTokenType.getSecurityTokenReference(),
                                ((WSSSecurityProperties) securityProperties).getDecryptionCrypto(),
                                ((WSSSecurityProperties)securityProperties).getCallbackHandler(),
                                inputProcessorChain.getSecurityContext(),
                                ((WSSSecurityProperties)securityProperties)
                        );
                        this.referencedSecurityToken.addWrappedToken(this);
                        return this.referencedSecurityToken;
                    }

                    @Override
                    protected Key getKey(String algorithmURI, XMLSecurityConstants.AlgorithmUsage algorithmUsage,
                                         String correlationID) throws XMLSecurityException {
                        byte[] secret;
                        InboundSecurityToken referencedSecurityToken = getReferencedSecurityToken();
                        if (referencedSecurityToken != null) {
                            if (referencedSecurityToken instanceof UsernameSecurityToken) {
                                UsernameSecurityToken usernameSecurityToken = (UsernameSecurityToken) referencedSecurityToken;
                                secret = usernameSecurityToken.generateDerivedKey();
                            } else {
                                secret = referencedSecurityToken.getSecretKey(algorithmURI, algorithmUsage, correlationID).getEncoded();
                            }
                        } else {
                            throw new WSSecurityException(WSSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, "unsupportedKeyId");
                        }
                        byte[] nonce = derivedKeyTokenType.getNonce();
                        if (nonce == null || nonce.length == 0) {
                            throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, "empty", "Missing wsc:Nonce value");
                        }
                        String derivedKeyAlgorithm = derivedKeyTokenType.getAlgorithm();
                        if (derivedKeyAlgorithm == null) {
                            derivedKeyAlgorithm = WSSConstants.P_SHA_1;
                        }
                        byte[] keyBytes = DerivedKeyUtils.deriveKey(
                                derivedKeyAlgorithm,
                                derivedKeyTokenType.getLabel(),
                                derivedKeyTokenType.getLength().intValue(),
                                secret,
                                nonce,
                                derivedKeyTokenType.getOffset().intValue()
                        );
                        XMLSecurityConstants.AlgorithmUsage derivedKeyAlgorithmUsage;
                        if (WSSConstants.Enc.equals(algorithmUsage)) {
                            derivedKeyAlgorithmUsage = WSSConstants.Enc_KD;
                        } else {
                            derivedKeyAlgorithmUsage = WSSConstants.Sig_KD;
                        }
                        AlgorithmSuiteSecurityEvent algorithmSuiteSecurityEvent = new AlgorithmSuiteSecurityEvent();
                        algorithmSuiteSecurityEvent.setAlgorithmURI(derivedKeyAlgorithm);
                        algorithmSuiteSecurityEvent.setAlgorithmUsage(derivedKeyAlgorithmUsage);
                        algorithmSuiteSecurityEvent.setKeyLength(keyBytes.length * 8);
                        algorithmSuiteSecurityEvent.setCorrelationID(correlationID);
                        inputProcessorChain.getSecurityContext().registerSecurityEvent(algorithmSuiteSecurityEvent);

                        String algo = JCEAlgorithmMapper.getJCEKeyAlgorithmFromURI(algorithmURI);
                        return new SecretKeySpec(keyBytes, algo);
                    }

                    @Override
                    public InboundSecurityToken getKeyWrappingToken() throws XMLSecurityException {
                        return getReferencedSecurityToken();
                    }

                    @Override
                    public WSSecurityTokenConstants.TokenType getTokenType() {
                        return WSSecurityTokenConstants.DerivedKeyToken;
                    }
                };
                this.derivedKeySecurityToken.setElementPath(elementPath);
                this.derivedKeySecurityToken.setXMLSecEvent(responsibleXMLSecStartXMLEvent);
                return this.derivedKeySecurityToken;
            }

            @Override
            public String getId() {
                return derivedKeyTokenType.getId();
            }
        };
        inputProcessorChain.getSecurityContext().registerSecurityTokenProvider(derivedKeyTokenType.getId(), securityTokenProvider);

        //fire a tokenSecurityEvent
        DerivedKeyTokenSecurityEvent derivedKeyTokenSecurityEvent = new DerivedKeyTokenSecurityEvent();
        derivedKeyTokenSecurityEvent.setSecurityToken(securityTokenProvider.getSecurityToken());
        derivedKeyTokenSecurityEvent.setCorrelationID(derivedKeyTokenType.getId());
        inputProcessorChain.getSecurityContext().registerSecurityEvent(derivedKeyTokenSecurityEvent);
    }
}
TOP

Related Classes of org.apache.wss4j.stax.impl.processor.input.DerivedKeyTokenInputHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.