Package org.apache.ws.security.processor

Source Code of org.apache.ws.security.processor.DerivedKeyTokenProcessor

/*
* Copyright  2003-2004 The Apache Software Foundation.
*
*  Licensed 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.ws.security.processor;

import org.apache.ws.security.WSDocInfo;
import org.apache.ws.security.WSPasswordCallback;
import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.conversation.ConversationConstants;
import org.apache.ws.security.conversation.dkalgo.AlgoFactory;
import org.apache.ws.security.conversation.dkalgo.DerivationAlgorithm;
import org.apache.ws.security.message.token.DerivedKeyToken;
import org.apache.ws.security.message.token.Reference;
import org.apache.ws.security.message.token.SecurityTokenReference;
import org.apache.ws.security.saml.SAMLKeyInfo;
import org.apache.ws.security.saml.SAMLUtil;
import org.apache.ws.security.util.Base64;
import org.w3c.dom.Element;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import java.io.IOException;
import java.util.Vector;

/**
* The processor to process <code>wsc:DerivedKeyToken</code>.
*
* @author Ruchith Fernando (ruchith.fernando@gmail.com)
*/
public class DerivedKeyTokenProcessor implements Processor {

    private String id;
    private byte[] keyBytes;
   
    private byte[] secret;
    private int length;
    private int offset;
    private byte[] nonce;
    private String label;
    private String algorithm;
   
    public void handleToken(Element elem, Crypto crypto, Crypto decCrypto,
            CallbackHandler cb, WSDocInfo wsDocInfo, Vector returnResults,
            WSSConfig config) throws WSSecurityException {
       
        //Deserialize the DKT
        DerivedKeyToken dkt = new DerivedKeyToken(elem);
       
        this.extractSecret(wsDocInfo, dkt, cb, crypto);
       
        String tempNonce = dkt.getNonce();
        if(tempNonce == null) {
            throw new WSSecurityException("Missing wsc:Nonce value");
        }
        this.nonce = Base64.decode(tempNonce);
       
        this.length = dkt.getLength();
   
        this.label = dkt.getLabel();
       
        this.algorithm = dkt.getAlgorithm();
       
        this.id = dkt.getID();

        if(length > 0) {
            this.deriveKey();
        }
    }

    private void deriveKey() throws WSSecurityException{
        try {
            DerivationAlgorithm algo = AlgoFactory.getInstance(this.algorithm);
            byte[] labelBytes = null;
            if(label == null || (label != null && label.length() == 0)) {
                labelBytes = (ConversationConstants.DEFAULT_LABEL + ConversationConstants.DEFAULT_LABEL)
                        .getBytes("UTF-8");
            } else {
                labelBytes = this.label.getBytes("UTF-8");
            }
           
            byte[] seed = new byte[labelBytes.length + nonce.length];
            System.arraycopy(labelBytes, 0, seed, 0, labelBytes.length);
            System.arraycopy(nonce, 0, seed, labelBytes.length, nonce.length);
           
            this.keyBytes = algo.createKey(this.secret, seed, offset, length);
           
        } catch (Exception e) {
            throw new WSSecurityException(WSSecurityException.FAILURE, e.getMessage());
        }
    }

    /**
     * @param wsDocInfo
     * @param dkt
     * @throws WSSecurityException
     */
    private void extractSecret(WSDocInfo wsDocInfo, DerivedKeyToken dkt, CallbackHandler cb, Crypto crypto)
            throws WSSecurityException {
        SecurityTokenReference str = dkt.getSecuityTokenReference();
        if (str != null) {
            Processor processor;
            String uri = null;
            String keyIdentifierValueType = null;
            String keyIdentifierValue = null;
           
            if(str.containsReference()) {
                Reference ref = str.getReference();
               
                uri = ref.getURI();
                processor = wsDocInfo.getProcessor(uri.substring(1));
            } else {
                //Contains key identifier
                keyIdentifierValue = str.getKeyIdentifierValue();
                keyIdentifierValueType = str.getKeyIdentifierValueType();
                processor = wsDocInfo.getProcessor(keyIdentifierValue);
            }
           
            if(processor == null && uri != null) {
                //Now use the callback and get it
                this.secret = this.getSecret(cb, uri.substring(1));
            } else if (processor == null && keyIdentifierValue != null
                && keyIdentifierValueType != null) {             
              this.secret = this.getSecret(cb, keyIdentifierValue, keyIdentifierValueType);
            } else if (processor instanceof EncryptedKeyProcessor) {
                this.secret = ((EncryptedKeyProcessor) processor)
                        .getDecryptedBytes();
            } else if (processor instanceof SecurityContextTokenProcessor) {
                this.secret = ((SecurityContextTokenProcessor) processor)
                        .getSecret();
            } else if (processor instanceof SAMLTokenProcessor) {
                SAMLTokenProcessor samlp = (SAMLTokenProcessor) processor;
                SAMLKeyInfo keyInfo = SAMLUtil.getSAMLKeyInfo(samlp
                        .getSamlTokenElement(), crypto, cb);
                //TODO Handle malformed SAML tokens where they don't have the
                //secret in them
                this.secret = keyInfo.getSecret();
            } else {
                throw new WSSecurityException(
                        WSSecurityException.FAILED_CHECK, "unsupportedKeyId");
            }
        } else {
            throw new WSSecurityException(WSSecurityException.FAILED_CHECK,
                    "noReference");
        }
    }

    private byte[] getSecret(CallbackHandler cb, String id)
            throws WSSecurityException {

        if (cb == null) {
            throw new WSSecurityException(WSSecurityException.FAILURE,
                    "noCallback");
        }

        WSPasswordCallback callback = new WSPasswordCallback(id, WSPasswordCallback.SECURITY_CONTEXT_TOKEN);
        Callback[] callbacks = new Callback[1];
        callbacks[0] = callback;
        try {
            cb.handle(callbacks);
        } catch (IOException e) {
            throw new WSSecurityException(WSSecurityException.FAILURE, "noKey",
                    new Object[] { id });
        } catch (UnsupportedCallbackException e) {
            throw new WSSecurityException(WSSecurityException.FAILURE, "noKey",
                    new Object[] { id });
        }

        return callback.getKey();
    }
   
    private byte[] getSecret(CallbackHandler cb, String keyIdentifierValue, String keyIdentifierType)
                                                             throws WSSecurityException {
     
        if (cb == null) {
            throw new WSSecurityException(WSSecurityException.FAILURE,
                    "noCallback");
        }
       
        WSPasswordCallback pwcb = null;
     
        //Handle the EncryptedKeySHA1 type key references
      if (keyIdentifierType.equals
          (SecurityTokenReference.ENC_KEY_SHA1_URI)) {

            pwcb = new WSPasswordCallback(keyIdentifierValue,
                                               WSPasswordCallback.ENCRYPTED_KEY_TOKEN);
            try {
              cb.handle(new Callback[]{pwcb});
            } catch (IOException e) {
                throw new WSSecurityException(WSSecurityException.FAILURE, "noKey",
                        new Object[] { id });
            } catch (UnsupportedCallbackException e) {
                throw new WSSecurityException(WSSecurityException.FAILURE, "noKey",
                        new Object[] { id });
            }
           
        }
      return pwcb.getKey();
    }
   
    /**
     * Returns the wsu:Id of the DerivedKeyToken
     * @see org.apache.ws.security.processor.Processor#getId()
     */
    public String getId() {
        return this.id;
    }

    /**
     * @return Returns the keyBytes.
     */
    public byte[] getKeyBytes() {
        return keyBytes;
    }
   
    /**
     * Get the derived key bytes for a given length
     * @return Returns the keyBytes.
     */
    public byte[] getKeyBytes(int len) throws WSSecurityException {
        this.length = len;
        this.deriveKey();
        return keyBytes;
    }

}
TOP

Related Classes of org.apache.ws.security.processor.DerivedKeyTokenProcessor

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.