Package org.apache.ws.sandbox.security.trust.message.token

Source Code of org.apache.ws.sandbox.security.trust.message.token.RequestedProofToken

/*
* 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.trust.message.token;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.sandbox.security.trust.TrustConstants;
import org.apache.ws.security.SOAPConstants;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSSecurityEngine;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.message.WSEncryptBody;
import org.apache.ws.security.message.token.BinarySecurity;
import org.apache.ws.security.message.token.Reference;
import org.apache.ws.security.message.token.SecurityTokenReference;
import org.apache.ws.security.message.token.X509Security;
import org.apache.ws.security.processor.EncryptedKeyProcessor;
import org.apache.ws.security.util.DOM2Writer;
import org.apache.ws.security.util.Loader;
import org.apache.ws.security.util.WSSecurityUtil;
import org.apache.xml.security.encryption.XMLCipher;
import org.apache.xml.security.encryption.XMLEncryptionException;
import org.apache.xml.security.keys.KeyInfo;
import org.apache.xml.security.keys.content.X509Data;
import org.apache.xml.security.keys.content.x509.XMLX509IssuerSerial;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.security.auth.callback.CallbackHandler;
import javax.xml.namespace.QName;

/**
* @author Dimuthu Leelarathne. (muthulee@yahoo.com)
* @author Ruchith Fernando
*/
public class RequestedProofToken {
    private static Log log =
            LogFactory.getLog(RequestedProofToken.class.getName());

    public static final QName TOKEN =
            new QName(TrustConstants.WST_NS, "RequestedProofToken");

    private Element element;
    private byte[] sharedSecret;

    /**
     * Constructor.
     *
     * @param doc    is the SOAP envelop.
     * @throws WSSecurityException
     */
    public RequestedProofToken(Document doc) throws WSSecurityException {
        this.element = doc.createElementNS(TrustConstants.WST_NS, TrustConstants.WST_PREFIX + ":" + TOKEN.getLocalPart());
        WSSecurityUtil.setNamespace(this.element, TOKEN.getNamespaceURI(), TrustConstants.WST_PREFIX);
        this.element.appendChild(doc.createTextNode(""));
        log.debug("RequestedProofToken : Document constructor, Element created.");
    }

    /**
     * COnstructor
     *
     * @param elem
     * @throws WSSecurityException
     */
    public RequestedProofToken(Element elem) throws WSSecurityException {
        this.element = elem;
        QName el = new QName(this.element.getNamespaceURI(),
                this.element.getLocalName());
        if (!el.equals(TOKEN)) {
            throw new WSSecurityException(WSSecurityException.INVALID_SECURITY_TOKEN,
                    "badTokenType00", new Object[]{el});
        }

        log.debug("RequestedProofToken :: Element constructor, Element created.");
    }

    /**
     * Method doDecryption
     *
     * @param callback
     * @param crypto
     * @throws WSSecurityException
     */
    public void doDecryption(String callback, Crypto crypto)
            throws WSSecurityException {
        WSSecurityEngine secEngine = new WSSecurityEngine();
        CallbackHandler cbHandler;

        // Element
        NodeList ndList =
                this.element.getElementsByTagNameNS("http://www.w3.org/2001/04/xmlenc#",
                        "EncryptedKey");
        if (ndList.getLength() < 1) {
            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
                    "RequestedProofToken is empty");
        }

        // CbHandler :: taken from WSSecurityEngine class
        if (callback != null) {
            Class cbClass = null;
            try {
                cbClass = Loader.loadClass(callback);
            } catch (ClassNotFoundException e) {
                throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC,
                        "RequestedProofToken: cannot load password callback class: "
                        + callback);
            }
            try {
                cbHandler = (CallbackHandler) cbClass.newInstance();
            } catch (java.lang.Exception e) {
                throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC,
                        "RequestedProofToken: cannot create instance of password callback: "
                        + callback +":: ErrMsg "+e.getMessage());
            }
            EncryptedKeyProcessor processor = new EncryptedKeyProcessor();
            processor.handleEncryptedKey((Element) ndList.item(0),
                    cbHandler,
                    crypto);

            this.sharedSecret = processor.getDecryptedBytes();
            log.debug(" RequestedProofToken, decryption ,Shared secret is :: " + new String(this.sharedSecret));
        } else {
            log.debug("RequestedProofToken :: CallbackHandler is null");
            throw new WSSecurityException(WSSecurityException.FAILURE, "CallbackHandler is null");
        }
        log.debug("RequestedProofToken :: Encryption done");
    }

    /**
     * Method doEncryptProof
     *
     * @param doc
     */
    //TODO :: Change the method signature.
    public void doEncryptProof(Document doc, Crypto crypto, String userInfo) throws WSSecurityException {
        WSEncryptBody wsEncrypt = new WSEncryptBody();
        try {
            wsEncrypt.setUserInfo(userInfo);
            wsEncrypt.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
            wsEncrypt.setParentNode(this.element);
            if (this.sharedSecret != null) {
                //wsEncrypt.setSymmetricKey(WSSecurityUtil.prepareSecretKey(WSConstants.TRIPLE_DES, this.sharedSecret));//TODO
            }
//            wsEncrypt.setParentNode(
//                (Element) (doc
//                    .getElementsByTagNameNS(
//                        WSConstants.WSSE_NS,
//                        "RequestedProofToken")
//                    .item(0)));
            wsEncrypt.build(doc, crypto);
            this.sharedSecret = wsEncrypt.getEncryptionKey().getEncoded();
        } catch (WSSecurityException e) {
            e.printStackTrace();
        }
        log.debug("RequestedProofToken :: Decryption Done");
    }

    public Element getElement() {
        return element;
    }

    public void setElement(Element element) {
        this.element = element;
    }

    public String toString() {
        return DOM2Writer.nodeToString((Node) this.element);
    }

    public void addToken(Element childToken) {
        this.element.appendChild(childToken);
    }

    public void removeToken(Element childToken) {
        this.element.removeChild(childToken);
    }

    /**
     * @return
     */
    public byte[] getSharedSecret() {
        return sharedSecret;
    }

    /**
     * @param bs
     */
    public void setSharedSecret(byte[] bs) {
        sharedSecret = bs;
    }

    public Document build(Document doc, Crypto crypto, String user, Element parentNode) throws WSSecurityException {
        boolean doDebug = log.isDebugEnabled();
        //TODO
        int keyIdentifierType = WSConstants.ISSUER_SERIAL;
        SecretKey symmetricKey = null;
        String symEncAlgo = WSConstants.TRIPLE_DES;
        String keyEncAlgo = WSConstants.KEYTRANSPORT_RSA15;

        if (doDebug) {
            log.debug("Beginning Encryption...");
        }

        /*
         * First step: set the encryption encoding namespace in the SOAP:Envelope
         */
        Element envelope = doc.getDocumentElement();
        envelope.setAttributeNS(WSConstants.XMLNS_NS,
                "xmlns:" + WSConstants.ENC_PREFIX,
                WSConstants.ENC_NS);

        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(envelope);

        /*
         * Second step: generate a symmetric key (session key) for
         * this alogrithm, and set the cipher into encryption mode.
         */
        KeyGenerator keyGen = null;
        try {
            keyGen = keyGen = KeyGenerator.getInstance("DESede");
        } catch (NoSuchAlgorithmException e2) {
            // TODO Auto-generated catch block
            e2.printStackTrace();
        }
        symmetricKey = keyGen.generateKey();
        XMLCipher xmlCipher = null;
        try {
            xmlCipher = XMLCipher.getInstance(symEncAlgo);
        } catch (XMLEncryptionException e3) {
            throw new WSSecurityException(WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e3);
        }


        /*
         * Fifth step: get the certificate that contains the public key for the
         * public key algorithm that will encrypt
         * the generated symmetric (session) key.
         * Up to now we support RSA 1-5 as public key algorithm
         */

        X509Certificate remoteCert = null;
        X509Certificate[] certs = crypto.getCertificates(user);
        if (certs == null || certs.length <= 0) {
            throw new WSSecurityException(WSSecurityException.FAILURE,
                    "invalidX509Data",
                    new Object[]{"for Encryption"});
        }
        remoteCert = certs[0];

        String certUri = "EncCertId-" + remoteCert.hashCode();

        Cipher cipher = null;//TODO
        //Cipher cipher = WSSecurityUtil.getCiperInstance(keyEncAlgo);//TODO
        try {
            cipher.init(Cipher.ENCRYPT_MODE, remoteCert);
        } catch (InvalidKeyException e) {
            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e);
        }
        byte[] encKey = symmetricKey.getEncoded();
        if (doDebug) {
            log.debug("cipher blksize: "
                    + cipher.getBlockSize()
                    + ", symm key length: "
                    + encKey.length);
        }
        if (cipher.getBlockSize() < encKey.length) {
            throw new WSSecurityException(WSSecurityException.FAILURE,
                    "unsupportedKeyTransp",
                    new Object[]{"public key algorithm too weak to encrypt symmetric key"});
        }
        byte[] encryptedKey = null;
        try {
            encryptedKey = cipher.doFinal(encKey);
        } catch (IllegalStateException e1) {
            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e1);
        } catch (IllegalBlockSizeException e1) {
            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e1);
        } catch (BadPaddingException e1) {
            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e1);
        }
        Text keyText =
                WSSecurityUtil.createBase64EncodedTextNode(doc, encryptedKey);

        Element xencEncryptedKey = WSEncryptBody.createEnrcyptedKey(doc, keyEncAlgo);

        WSSecurityUtil.prependChildElement(doc,
                parentNode,
                xencEncryptedKey,
                true);

        SecurityTokenReference secToken = null;//new SecurityTokenReference(doc); TODO

        switch (keyIdentifierType) {
            case WSConstants.X509_KEY_IDENTIFIER:
                secToken.setKeyIdentifier(remoteCert);
                // build a key id class??
                break;

            case WSConstants.SKI_KEY_IDENTIFIER:
                secToken.setKeyIdentifierSKI(remoteCert, crypto);
                break;

            case WSConstants.ISSUER_SERIAL:
                XMLX509IssuerSerial data = new XMLX509IssuerSerial(doc, remoteCert);
                X509Data x509Data = new X509Data(doc);
                x509Data.add(data);
                secToken.setX509IssuerSerial(x509Data);
                WSSecurityUtil.setNamespace(secToken.getElement(), WSConstants.WSSE_NS, WSConstants.WSSE_PREFIX);
                break;

            case WSConstants.BST_DIRECT_REFERENCE:
                BinarySecurity bstToken = null;
                bstToken = new X509Security(doc);
                ((X509Security) bstToken).setX509Certificate(remoteCert);
                bstToken.setID(certUri);
                Reference ref = new Reference(doc);
                ref.setURI("#" + certUri);
                ref.setValueType(bstToken.getValueType());
                secToken.setReference(ref);
//                WSSecurityUtil.prependChildElement(
//                    doc,
//                    wsseSecurity,
//                    bstToken.getElement(),
//                    false);
                break;

            default :
                throw new WSSecurityException(WSSecurityException.FAILURE,
                        "unsupportedKeyId");
        }
        KeyInfo keyInfo = new KeyInfo(doc);
        keyInfo.addUnknownElement(secToken.getElement());
        WSSecurityUtil.appendChildElement(doc, xencEncryptedKey, keyInfo.getElement());

        Element xencCipherValue = WSEncryptBody.createCipherValue(doc, xencEncryptedKey);
        xencCipherValue.appendChild(keyText);
        //    createDataRefList(doc, xencEncryptedKey, encDataRefs);
        log.debug("Encryption complete.");
        return doc;
    }

}
TOP

Related Classes of org.apache.ws.sandbox.security.trust.message.token.RequestedProofToken

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.