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

org.apache.ws.security.message.WSSecDKEncrypt Maven / Gradle / Ivy

Go to download

Apache WSS4J is an implementation of the Web Services Security (WS-Security) being developed at OASIS Web Services Security TC. WSS4J is a primarily a Java library that can be used to sign and verify SOAP Messages with WS-Security information. WSS4J will use Apache Axis and Apache XML-Security projects and will be interoperable with JAX-RPC based server/clients and .NET server/clients.

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

import org.apache.ws.security.SOAPConstants;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSEncryptionPart;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.conversation.ConversationException;
import org.apache.ws.security.message.token.Reference;
import org.apache.ws.security.message.token.SecurityTokenReference;
import org.apache.ws.security.util.WSSecurityUtil;
import org.apache.xml.security.encryption.EncryptedData;
import org.apache.xml.security.encryption.XMLCipher;
import org.apache.xml.security.encryption.XMLEncryptionException;
import org.apache.xml.security.keys.KeyInfo;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import javax.crypto.SecretKey;

import java.util.Vector;

/**
 * Encrypts and signs parts of a message with derived keys derived from a
 * symmetric key. This symmetric key will be included as an EncryptedKey
 * 
 * @author Ruchith Fernando ([email protected])
 */
public class WSSecDKEncrypt extends WSSecDerivedKeyBase {

    protected String symEncAlgo = WSConstants.AES_128;
    
    public Document build(Document doc, WSSecHeader secHeader)
            throws WSSecurityException, ConversationException {
        
        /*
         * Setup the encrypted key
         */
        prepare(doc);
        
        this.envelope =  doc.getDocumentElement();
        /*
         * prepend elements in the right order to the security header
         */
        prependDKElementToHeader(secHeader);
                
        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(envelope);
        if (parts == null) {
            parts = new Vector();
            WSEncryptionPart encP = new WSEncryptionPart(soapConstants
                    .getBodyQName().getLocalPart(), soapConstants
                    .getEnvelopeURI(), "Content");
            parts.add(encP);
        }
        Element externRefList = encryptForExternalRef(null, parts);
        addExternalRefElement(externRefList, secHeader);

        return doc;
    }

    private Vector doEncryption(Document doc, byte[] secretKey, Vector references) throws WSSecurityException {

        SecretKey key = WSSecurityUtil.prepareSecretKey(this.symEncAlgo, secretKey);
        
        
        XMLCipher xmlCipher = null;
        try {
            xmlCipher = XMLCipher.getInstance(symEncAlgo);
        } catch (XMLEncryptionException e3) {
            throw new WSSecurityException(
                    WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e3);
        }

        Vector encDataRefs = new Vector();
        
        if(envelope == null) {
            envelope = doc.getDocumentElement();
        }
        
        for (int part = 0; part < references.size(); part++) {
            WSEncryptionPart encPart = (WSEncryptionPart) references.get(part);

            String idToEnc = encPart.getId();
            
            String elemName = encPart.getName();
            String nmSpace = encPart.getNamespace();
            String modifier = encPart.getEncModifier();
            /*
             * Third step: get the data to encrypt.
             */
            Element body = null;
            if (idToEnc != null) {
                body = WSSecurityUtil.findElementById(document
                        .getDocumentElement(), idToEnc, WSConstants.WSU_NS);
                if (body == null) {
                    body = WSSecurityUtil.findElementById(document
                            .getDocumentElement(), idToEnc, null);
                }
            } else {
                body = (Element) WSSecurityUtil.findElement(envelope, elemName,
                        nmSpace);
            }
            if (body == null) {
                throw new WSSecurityException(WSSecurityException.FAILURE,
                        "noEncElement", new Object[] { "{" + nmSpace + "}"
                                + elemName });
            }

            boolean content = modifier.equals("Content") ? true : false;
            String xencEncryptedDataId = "EncDataId-" + body.hashCode();

            /*
             * Forth step: encrypt data, and set necessary attributes in
             * xenc:EncryptedData
             */
            try {
                //Create the SecurityTokenRef to the DKT
                KeyInfo keyInfo = new KeyInfo(document);
                SecurityTokenReference secToken = new SecurityTokenReference(document);
                Reference ref = new Reference(document);
                ref.setURI("#" + dktId);
                secToken.setReference(ref);

                keyInfo.addUnknownElement(secToken.getElement());

                xmlCipher.init(XMLCipher.ENCRYPT_MODE, key);
                EncryptedData encData = xmlCipher.getEncryptedData();
                encData.setId(xencEncryptedDataId);
                encData.setKeyInfo(keyInfo);
                xmlCipher.doFinal(doc, body, content);
            } catch (Exception e2) {
                throw new WSSecurityException(
                        WSSecurityException.FAILED_ENCRYPTION, null, null, e2);
            }
            encDataRefs.add(new String("#" + xencEncryptedDataId));
        }
        return encDataRefs;
    }
    
    /**
     * Encrypt one or more parts or elements of the message (external).
     * 
     * This method takes a vector of WSEncryptionPart object that
     * contain information about the elements to encrypt. The method call the
     * encryption method, takes the reference information generated during
     * encryption and add this to the xenc:Reference element.
     * This method can be called after prepare() and can be
     * called multiple times to encrypt a number of parts or elements.
     * 
     * 

* * The method generates a xenc:Reference element that must * be added to the SecurityHeader. See addExternalRefElement(). * *

* * If the dataRef parameter is null the method * creates and initializes a new Reference element. * * @param dataRef * A xenc:Reference element or null * @param references * A vector containing WSEncryptionPart objects * @return Returns the updated xenc:Reference element * @throws WSSecurityException */ public Element encryptForExternalRef(Element dataRef, Vector references) throws WSSecurityException { Vector encDataRefs = doEncryption(document, derivedKeyBytes, references); Element referenceList = dataRef; if (referenceList == null) { referenceList = document.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":ReferenceList"); } createDataRefList(document, referenceList, encDataRefs); return referenceList; } /** * Adds (prepends) the external Reference element to the Security header. * * The reference element must be created by the * encryptForExternalRef() method. The method adds the * reference element in the SecurityHeader. * * @param dataRef * The external enc:Reference element * @param secHeader * The security header. */ public void addExternalRefElement(Element referenceList, WSSecHeader secHeader) { Node node = dkt.getElement().getNextSibling(); if(node == null || (node != null && !(node instanceof Element))) { //If (at this moment) DerivedKeyToken is the LAST element of //the security header secHeader.getSecurityHeader().appendChild(referenceList); } else { secHeader.getSecurityHeader().insertBefore(referenceList, node); } } public static Element createDataRefList(Document doc, Element referenceList, Vector encDataRefs) { for (int i = 0; i < encDataRefs.size(); i++) { String dataReferenceUri = (String) encDataRefs.get(i); Element dataReference = doc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":DataReference"); dataReference.setAttributeNS(null, "URI", dataReferenceUri); referenceList.appendChild(dataReference); } return referenceList; } public void setSymmetricEncAlgorithm(String algo) { symEncAlgo = algo; } /** * @see org.apache.ws.security.message.WSSecDerivedKeyBase#getDerivedKeyLength() */ protected int getDerivedKeyLength() throws WSSecurityException{ return (this.derivedKeyLength > 0) ? this.derivedKeyLength : WSSecurityUtil.getKeyLength(this.symEncAlgo); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy