Package org.apache.ws.sandbox.security.conversation

Source Code of org.apache.ws.sandbox.security.conversation.KeyDerivator

/*
* 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.sandbox.security.conversation;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.sandbox.security.conversation.dkalgo.AlgoFactory;
import org.apache.ws.sandbox.security.conversation.dkalgo.DerivationAlgorithm;
import org.apache.ws.sandbox.security.conversation.message.info.DerivedKeyInfo;
import org.apache.ws.security.message.token.SecurityTokenReference;

import java.util.Hashtable;

/**
* @author Ruchith
* @version 1.0
*/

public class KeyDerivator {

    private Log log = LogFactory.getLog(KeyDerivator.class.getName());

    public byte[] generateKey(Hashtable sessionTable, String identifier) throws
            WSSecurityException, ConversationException, WSSecurityException {

        log.debug("KeyDerivator: Inside generate key");
        String[] uuidAndDerivedKeyTokenId = ConversationUtil.
                getUuidAndDerivedKeyTokenId(identifier);
        //Get the session from teh session table
        ConversationSession convSession = (ConversationSession) sessionTable.get(uuidAndDerivedKeyTokenId[0]);
        log.debug("KeyDerivator: session found: " + uuidAndDerivedKeyTokenId[0]);
        if (convSession != null) {
            int freq = convSession.getContextInfo().getFrequency(); //Key generation frequency
            if (freq == 0) { //If the frequency is zero then no need for key derivation
                return convSession.getContextInfo().getSharedSecret();
            } else { //Derived keys are required
                return deriveKey(convSession, uuidAndDerivedKeyTokenId[1]);
            }
        } else {
            /** @todo Check the list of expired sessions and figureout whether the session is expired or not */
            throw new ConversationException("Conversation Session not found");
        }
    }

    private byte[] deriveKey(ConversationSession convSession,
                             String derivedKeyTokenId) throws
            WSSecurityException, ConversationException {

        //The derived key info object of the current derived key
        DerivedKeyInfo dkInfo = (DerivedKeyInfo) convSession.getDerivedKeys().get(derivedKeyTokenId);
        SecurityTokenReference secTokRef = dkInfo.getSecurityTokenReference();
        log.debug("KeyDerivator: deriveKey: security token reference: " + secTokRef);
//        if (secTokRef != null) {
//            if (secTokRef.toString().equals("<wsse:SecurityTokenReference/>")) {//No security token reference
//                log.debug("KeyDerivator: deriveKey: No security token refernece available");
//                return deriveTokenFromContext(convSession, dkInfo);
//            } else {
//                String contextIdentifier = convSession.getContextInfo().getIdentifier();
//
//                String wsuId = secTokRef.getReference().getURI();
//
//                Element sctEle = WSSecurityUtil.getElementByWsuId(WSSConfig.getDefaultWSConfig(), secTokRef.getElement().getOwnerDocument(), wsuId);
//
//                try {
//                    SecurityContextToken sct = new SecurityContextToken(sctEle);
//                    if (contextIdentifier.equals(sct.getIdentifier()))
//                        return deriveTokenFromContext(convSession, dkInfo);
//                    else
//                        throw new ConversationException("Derivation source cannot be determined");
//                } catch (WSSecurityException secEx) {
//                    /** @todo Supporting other tokens other than SCT as the derivation source */
//                    //Here we should check whether it is some other type of a token
//                    //E.g. DerivedKeyToken
//                }
//
//                if (secTokRef.getReference().getURI().equals(contextIdentifier)) { //If the reference is to the SecurityContextToken
//                    return deriveTokenFromContext(convSession, dkInfo);
//                } else {
//                    //Derive from some other security token other than the relevent security context
//                    /** @todo Derive from some other security token other than the relevent security context
//                     * For example this can be another DerivedKeyToken
//                     * */
//                    throw new ConversationException("KeyDerivator:  Deriving from some " +
//                            "other security token other than the " +
//                            "relevent security context: Not implemented :-(");
//
//                }
//            }
//        } else { //There is no SecurityTokenRefernece
            log.debug("KeyDerivator: deriveKey: No security token refernece available");
            return deriveTokenFromContext(convSession, dkInfo);
  //      }

    }

    /**
     * Derive the key from the related security context information
     *
     * @param convSession
     * @param dkInfo
     * @return
     * @throws ConversationException
     */
    private byte[] deriveTokenFromContext(ConversationSession convSession,
                                          DerivedKeyInfo dkInfo) throws
            ConversationException {

        log.debug("KeyDerivator: deriving key from contecxt :" + convSession.getContextInfo().getIdentifier() + " for dkt: " + dkInfo.getId());
        byte[] secret = convSession.getContextInfo().getSharedSecret(); //Shared secret
        String labelAndNonce = getLabelAndNonce(convSession, dkInfo); //Label and nonce
        long keyLength = getKeyLength(convSession, dkInfo); //Length of the key to generated
        int offset = getOffset(convSession, dkInfo);
        DerivationAlgorithm derivationAlgo = AlgoFactory.getInstance(dkInfo.
                getAlgorithm()); //Derivation algorithm
        return derivationAlgo.createKey(secret, labelAndNonce, offset, keyLength);
    }

    /**
     * The label+nonce value used for the seed in calculating the derived key
     *
     * @param convSession
     * @param dkInfo
     * @return relevan label+nonce
     */
    private String getLabelAndNonce(ConversationSession convSession,
                                    DerivedKeyInfo dkInfo) throws
            ConversationException {
        String label, nonce;
        if ((label = dkInfo.getLabel()) != null || (label = convSession.getLabel()) != null) {
            if ((nonce = dkInfo.getNonce()) != null) {
                log.debug("KeyDerivator: Inside get label and nocne : " + label + nonce);
                return label + nonce;
            } else {
                throw new ConversationException("Nonce value not available");
            }
        } else {
            throw new ConversationException("Label cannot be found");
        }
    }

    /**
     * This return teh key length of the derived key to be generated
     *
     * @param convSession
     * @param dkInfo
     * @return length of the key to be returned
     * @throws ConversationException
     */
    private long getKeyLength(ConversationSession convSession,
                              DerivedKeyInfo dkInfo) throws ConversationException {

        long length;
        if ((length = dkInfo.getLength()) != -1) { //If the length info is there in the token return it
            log.debug("KeyDerivator: Inside get length: " + length);
            return length;
        } else if ((length = convSession.getKeyLength()) != -1) { //Get length info from the session
            log.debug("KeyDerivator: Inside get length: " + length);
            return length;
        } else {
            throw new ConversationException("Length information not available");
        }
    }

    /**
     * @param convSession
     * @param dkInfo
     * @return
     * @throws ConversationException
     */
    private int getOffset(ConversationSession convSession, DerivedKeyInfo dkInfo) throws
            ConversationException {
        int offset = dkInfo.getOffset();
        int generation = dkInfo.getGeneration();
        long lengthFromDkInfo = dkInfo.getLength();

        if (generation != -1 && offset != -1) { //If both generation and offset values are set
            throw new ConversationException("Generation and Offset both cannot be used simultaneously: " +
                    "Generation : " + generation +
                    "Offset : " + offset);
        } else if (convSession.getKeyLength() != -1) { //Session is configured to use fixed size keys
            if (generation == -1){
              log.debug("Generation set to zero");
              generation = 0;  
          return (int)convSession.getKeyLength() * generation;
//                throw new ConversationException("Generation value is not avaliable (fixed size keys are used: " +
//                        "Key size : " + convSession.getKeyLength() + ")");
            }else{
                return (int) convSession.getKeyLength() * generation;
            }   
        } else if (offset != -1) { //Fixed size keys are NOT used: The length and offset values should be available in the DKT
            return offset;
        } else if (generation != -1) { //Here length should be specified in the DKT
            if (dkInfo.getLength() != -1)
                return generation * (int) dkInfo.getLength();
            else
                throw new ConversationException("Length information not available");
        } else {
            return 0; //If generation and offset info are not available offset will be 0
        }
    }

}
TOP

Related Classes of org.apache.ws.sandbox.security.conversation.KeyDerivator

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.