You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fx-dev@ws.apache.org by ru...@apache.org on 2006/02/10 13:42:21 UTC

svn commit: r376649 - in /webservices/wss4j/trunk: src/org/apache/ws/security/message/ src/org/apache/ws/security/util/ test/wssec/

Author: ruchithf
Date: Fri Feb 10 04:42:19 2006
New Revision: 376649

URL: http://svn.apache.org/viewcvs?rev=376649&view=rev
Log:
- Added a builder for derived key signature
- Added a test method to test signature building(sig verification - in progress ...)
- Refactored the derived key builders to move the common methods to a base class: WSSecDerivedKeyBase


Added:
    webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDKSign.java
    webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDerivedKeyBase.java
Modified:
    webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDKSignEncrypt.java
    webservices/wss4j/trunk/src/org/apache/ws/security/util/WSSecurityUtil.java
    webservices/wss4j/trunk/test/wssec/TestWSSecurityNewDK.java

Added: webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDKSign.java
URL: http://svn.apache.org/viewcvs/webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDKSign.java?rev=376649&view=auto
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDKSign.java (added)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDKSign.java Fri Feb 10 04:42:19 2006
@@ -0,0 +1,435 @@
+
+package org.apache.ws.security.message;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Vector;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSDocInfoStore;
+import org.apache.ws.security.WSEncryptionPart;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.message.token.Reference;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.saml.SAMLUtil;
+import org.apache.ws.security.transform.STRTransform;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.algorithms.SignatureAlgorithm;
+import org.apache.xml.security.c14n.Canonicalizer;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.signature.XMLSignatureException;
+import org.apache.xml.security.transforms.TransformationException;
+import org.apache.xml.security.transforms.Transforms;
+import org.apache.xml.security.transforms.params.InclusiveNamespaces;
+import org.apache.xml.security.utils.Constants;
+import org.apache.xml.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+/**
+ * Builder to sign with derived keys
+ * 
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ * @author Davanum Srinivas (dims@yahoo.com)
+ * @author Werner Dittmann (werner@apache.org)
+ */
+public class WSSecDKSign extends WSSecDerivedKeyBase {
+
+    private static Log log = LogFactory.getLog(WSSecDKSign.class.getName());
+
+    protected String sigAlgo = XMLSignature.ALGO_ID_MAC_HMAC_SHA1;
+
+    protected String canonAlgo = Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
+
+    protected byte[] signatureValue = null;
+    
+    private XMLSignature sig = null;
+    
+    private KeyInfo keyInfo = null;
+
+    private String keyInfoUri = null;
+
+    private SecurityTokenReference secRef = null;
+
+    private String strUri = null;
+    
+    private WSDocInfo wsDocInfo;
+
+    public Document build(Document doc, Crypto crypto, WSSecHeader secHeader) throws WSSecurityException  {
+        
+        this.prepareSig(doc, crypto, secHeader);
+        
+        /*
+         * prepend elements in the right order to the security header
+         */
+        prependDKElementToHeader(secHeader);
+        prependToHeader(secHeader);
+        prependBSTElementToHeader(secHeader);
+        
+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc
+                .getDocumentElement());
+
+        if (parts == null) {
+            parts = new Vector();
+            WSEncryptionPart encP = new WSEncryptionPart(soapConstants
+                    .getBodyQName().getLocalPart(), soapConstants
+                    .getEnvelopeURI(), "Content");
+            parts.add(encP);
+        }
+        
+        addReferencesToSign(parts, secHeader);
+        
+        prependToHeader(secHeader);
+        
+        computeSignature();
+        
+        return doc;
+    }
+    
+    protected void prepareSig(Document doc, Crypto crypto, WSSecHeader secHeader)
+                            throws WSSecurityException {
+        this.prepare(doc, crypto);
+        
+        wsDocInfo = new WSDocInfo(doc.hashCode());
+        wsDocInfo.setCrypto(crypto);
+        
+        /*
+         * Get an initialize a XMLSignature element.
+         */
+        if (canonAlgo.equals(WSConstants.C14N_EXCL_OMIT_COMMENTS)) {
+            Element canonElem = XMLUtils.createElementInSignatureSpace(doc,
+                    Constants._TAG_CANONICALIZATIONMETHOD);
+
+            canonElem.setAttributeNS(null, Constants._ATT_ALGORITHM, canonAlgo);
+
+            if (wssConfig.isWsiBSPCompliant()) {
+                Set prefixes = getInclusivePrefixes(secHeader
+                        .getSecurityHeader(), false);
+
+                InclusiveNamespaces inclusiveNamespaces = new InclusiveNamespaces(
+                        doc, prefixes);
+
+                canonElem.appendChild(inclusiveNamespaces.getElement());
+            }
+
+            try {
+                SignatureAlgorithm signatureAlgorithm = new SignatureAlgorithm(
+                        doc, sigAlgo);
+                sig = new XMLSignature(doc, null, signatureAlgorithm
+                        .getElement(), canonElem);
+            } catch (XMLSecurityException e) {
+                log.error("", e);
+                throw new WSSecurityException(
+                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig");
+            }
+        } else {
+            try {
+                sig = new XMLSignature(doc, null, sigAlgo, canonAlgo);
+            } catch (XMLSecurityException e) {
+                log.error("", e);
+                throw new WSSecurityException(
+                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig");
+            }
+        }
+        
+        sig.addResourceResolver(EnvelopeIdResolver.getInstance());
+        String sigUri = "Signature-" + sig.hashCode();
+        sig.setId(sigUri);
+        
+        keyInfo = sig.getKeyInfo();
+        keyInfoUri = "KeyId-" + keyInfo.hashCode();
+        keyInfo.setId(keyInfoUri);
+        
+        secRef = new SecurityTokenReference(doc);
+        strUri = "STRId-" + secRef.hashCode();
+        secRef.setID(strUri);
+        
+        Reference refUt = new Reference(document);
+        refUt.setURI("#" + this.dktId);
+        secRef.setReference(refUt);
+        
+        keyInfo.addUnknownElement(secRef.getElement());
+    }
+    
+    
+    protected Set getInclusivePrefixes(Element target) {
+        return getInclusivePrefixes(target, true);
+    }
+
+    protected Set getInclusivePrefixes(Element target, boolean excludeVisible) {
+        Set result = new HashSet();
+        Node parent = target;
+        NamedNodeMap attributes;
+        Node attribute;
+        while (!(parent.getParentNode() instanceof Document)) {
+            parent = parent.getParentNode();
+            attributes = parent.getAttributes();
+            for (int i = 0; i < attributes.getLength(); i++) {
+                attribute = attributes.item(i);
+                if (attribute.getNamespaceURI() != null
+                        && attribute.getNamespaceURI().equals(
+                                org.apache.ws.security.WSConstants.XMLNS_NS)) {
+                    if (attribute.getNodeName().equals("xmlns")) {
+                        result.add("#default");
+                    } else {
+                        result.add(attribute.getLocalName());
+                    }
+                }
+            }
+        }
+
+        if (excludeVisible == true) {
+            attributes = target.getAttributes();
+            for (int i = 0; i < attributes.getLength(); i++) {
+                attribute = attributes.item(i);
+                if (attribute.getNamespaceURI() != null
+                        && attribute.getNamespaceURI().equals(
+                                org.apache.ws.security.WSConstants.XMLNS_NS)) {
+                    if (attribute.getNodeName().equals("xmlns")) {
+                        result.remove("#default");
+                    } else {
+                        result.remove(attribute.getLocalName());
+                    }
+                }
+                if (attribute.getPrefix() != null) {
+                    result.remove(attribute.getPrefix());
+                }
+            }
+
+            if (target.getPrefix() == null) {
+                result.remove("#default");
+            } else {
+                result.remove(target.getPrefix());
+            }
+        }
+
+        return result;
+    }
+    
+    /**
+     * This method adds references to the Signature.
+     * 
+     * The added references are signed when calling
+     * <code>computeSignature()</code>. This method can be called several
+     * times to add references as required. <code>addReferencesToSign()</code>
+     * can be called anytime after <code>prepare</code>.
+     * 
+     * @param references
+     *            A vector containing <code>WSEncryptionPart</code> objects
+     *            that define the parts to sign.
+     * @param secHeader
+     *            Used to compute namespaces to be inserted by
+     *            InclusiveNamespaces to be WSI compliant.
+     * @throws WSSecurityException
+     */
+    public void addReferencesToSign(Vector references, WSSecHeader secHeader)
+            throws WSSecurityException {
+        Transforms transforms = null;
+
+        Element envelope = document.getDocumentElement();
+
+        for (int part = 0; part < references.size(); part++) {
+            WSEncryptionPart encPart = (WSEncryptionPart) references.get(part);
+
+            String idToSign = encPart.getId();
+
+            String elemName = encPart.getName();
+            String nmSpace = encPart.getNamespace();
+
+            /*
+             * Set up the elements to sign. There are two resevered element
+             * names: "Token" and "STRTransform" "Token": Setup the Signature to
+             * either sign the information that points to the security token or
+             * the token itself. If its a direct reference sign the token,
+             * otherwise sign the KeyInfo Element. "STRTransform": Setup the
+             * ds:Reference to use STR Transform
+             * 
+             */
+            transforms = new Transforms(document);
+            try {
+                if (idToSign != null) {
+                    Element toSignById = WSSecurityUtil.findElementById(
+                            document.getDocumentElement(), idToSign,
+                            WSConstants.WSU_NS);
+                    if (toSignById == null) {
+                        toSignById = WSSecurityUtil.findElementById(document
+                                .getDocumentElement(), idToSign, null);
+                    }
+                    transforms
+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    if (wssConfig.isWsiBSPCompliant()) {
+                        transforms.item(0).getElement().appendChild(
+                                new InclusiveNamespaces(document,
+                                        getInclusivePrefixes(toSignById))
+                                        .getElement());
+                    }
+                    sig.addDocument("#" + idToSign, transforms);
+                } else if (elemName.equals("Token")) {
+                    transforms
+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    if (wssConfig.isWsiBSPCompliant()) {
+                        transforms.item(0).getElement().appendChild(
+                                new InclusiveNamespaces(document,
+                                        getInclusivePrefixes(keyInfo
+                                                .getElement()))
+                                        .getElement());
+                    }
+                    sig.addDocument("#" + keyInfoUri, transforms);
+                } else if (elemName.equals("STRTransform")) { // STRTransform
+                    Element ctx = createSTRParameter(document);
+                    transforms.addTransform(
+                            STRTransform.implementedTransformURI, ctx);
+                    sig.addDocument("#" + strUri, transforms);
+                } else if (elemName.equals("Assertion")) { // Assertion
+
+                    String id = null;
+                    id = SAMLUtil.getAssertionId(envelope, elemName, nmSpace);
+
+                    Element body = (Element) WSSecurityUtil.findElement(
+                            envelope, elemName, nmSpace);
+                    if (body == null) {
+                        throw new WSSecurityException(
+                                WSSecurityException.FAILURE, "noEncElement",
+                                new Object[] { nmSpace + ", " + elemName });
+                    }
+                    transforms
+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    if (wssConfig.isWsiBSPCompliant()) {
+                        transforms.item(0).getElement().appendChild(
+                                new InclusiveNamespaces(document,
+                                        getInclusivePrefixes(body))
+                                        .getElement());
+                    }
+                    String prefix = WSSecurityUtil.setNamespace(body,
+                            WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
+                    body.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);
+                    sig.addDocument("#" + id, transforms);
+
+                } else {
+                    Element body = (Element) WSSecurityUtil.findElement(
+                            envelope, elemName, nmSpace);
+                    if (body == null) {
+                        throw new WSSecurityException(
+                                WSSecurityException.FAILURE, "noEncElement",
+                                new Object[] { nmSpace + ", " + elemName });
+                    }
+                    transforms
+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    if (wssConfig.isWsiBSPCompliant()) {
+                        transforms.item(0).getElement().appendChild(
+                                new InclusiveNamespaces(document,
+                                        getInclusivePrefixes(body))
+                                        .getElement());
+                    }
+                    sig.addDocument("#" + setWsuId(body), transforms);
+                }
+            } catch (TransformationException e1) {
+                throw new WSSecurityException(
+                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null,
+                        e1);
+            } catch (XMLSignatureException e1) {
+                throw new WSSecurityException(
+                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null,
+                        e1);
+            }
+        }
+    }
+    
+    protected Element createSTRParameter(Document doc) {
+        Element transformParam = doc.createElementNS(WSConstants.WSSE_NS,
+                WSConstants.WSSE_PREFIX + ":TransformationParameters");
+
+        WSSecurityUtil.setNamespace(transformParam, WSConstants.WSSE_NS,
+                WSConstants.WSSE_PREFIX);
+
+        Element canonElem = doc.createElementNS(WSConstants.SIG_NS,
+                WSConstants.SIG_PREFIX + ":CanonicalizationMethod");
+
+        WSSecurityUtil.setNamespace(canonElem, WSConstants.SIG_NS,
+                WSConstants.SIG_PREFIX);
+
+        canonElem.setAttributeNS(null, "Algorithm",
+                Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
+        transformParam.appendChild(canonElem);
+        return transformParam;
+    }
+    
+    
+    /**
+     * Prepends the Signature element to the elements already in the Security
+     * header.
+     * 
+     * The method can be called any time after <code>prepare()</code>.
+     * This allows to insert the Signature element at any position in the
+     * Security header.
+     * 
+     * @param securityHeader
+     *            The secHeader that holds the Signature element.
+     */
+    public void prependToHeader(WSSecHeader secHeader) {
+        WSSecurityUtil.prependChildElement(document, secHeader.getSecurityHeader(), sig
+                .getElement(), false);
+    }
+    
+    
+    /**
+     * Compute the Signature over the references.
+     * 
+     * After references are set this method computes the Signature for them.
+     * This method can be called anytime after the references were set. See
+     * <code>addReferencesToSign()</code>.
+     * 
+     * @throws WSSecurityException
+     */
+    public void computeSignature() throws WSSecurityException {
+        WSDocInfoStore.store(wsDocInfo);
+        try {
+            sig.sign(sig.createSecretKey(derivedKeyBytes));
+            signatureValue = sig.getSignatureValue();
+        } catch (XMLSignatureException e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
+                    null, null, e1);
+        } catch (Exception e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
+                    null, null, e1);
+        } finally {
+            WSDocInfoStore.delete(wsDocInfo);
+        }
+
+    }
+    
+    /**
+     * @see org.apache.ws.security.message.WSSecDerivedKeyBase#getDerivedKeyLength()
+     */
+    protected int getDerivedKeyLength() throws WSSecurityException {
+        if(XMLSignature.ALGO_ID_MAC_HMAC_SHA1.equals(sigAlgo)) {
+            return 20;
+        } else if(XMLSignature.ALGO_ID_MAC_HMAC_SHA256.equals(sigAlgo)) {
+            return 32;
+        } else if(XMLSignature.ALGO_ID_MAC_HMAC_SHA384.equals(sigAlgo)) {
+            return 48;
+        } else if(XMLSignature.ALGO_ID_MAC_HMAC_SHA512.equals(sigAlgo)) {
+            return 64;
+        } else if(XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5.equals(sigAlgo)) {
+            return 16;
+        } else {
+            throw new WSSecurityException(WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, null);
+        }
+    }
+    
+    
+    public void setSignatureAlgorithm(String algo) {
+        this.sigAlgo = algo;
+    }
+    
+
+}

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDKSignEncrypt.java
URL: http://svn.apache.org/viewcvs/webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDKSignEncrypt.java?rev=376649&r1=376648&r2=376649&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDKSignEncrypt.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDKSignEncrypt.java Fri Feb 10 04:42:19 2006
@@ -17,45 +17,25 @@
 
 package org.apache.ws.security.message;
 
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.cert.X509Certificate;
 import java.util.Vector;
 
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
 import javax.crypto.SecretKey;
 
-import org.apache.axis.encoding.Base64;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.ws.security.SOAPConstants;
 import org.apache.ws.security.WSConstants;
 import org.apache.ws.security.WSEncryptionPart;
-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.BinarySecurity;
-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.message.token.X509Security;
 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.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.Text;
 
 /**
  * Encrypts and signes parts of a message with derived keys derived from a
@@ -63,39 +43,11 @@
  * 
  * @author Ruchith Fernando (ruchith.fernando@gmail.com)
  */
-public class WSSecDKSignEncrypt extends WSSecBase {
+public class WSSecDKSignEncrypt extends WSSecDerivedKeyBase {
 
-    private static Log log = LogFactory.getLog(WSSecEncrypt.class.getName());
-
-    private static Log tlog = LogFactory.getLog("org.apache.ws.security.TIME");
-
-    private Document document;
-    
     protected String symEncAlgo = WSConstants.AES_128;
-
-    protected String keyEncAlgo = WSConstants.KEYTRANSPORT_RSA15;
-    
-    protected String encrUser = null;
-    
-    private byte[] ephemeralKey;
-    
-    private byte[] derivedSigKey;
     
-    private byte[] derivedEncrKey;
-
-    private Element xencEncryptedKey;
-
-    private String encKeyId = null;
-    
-    private BinarySecurity bstToken = null;
-
-    private Element envelope;
-    
-    private DerivedKeyToken dkt = null;
-    
-    private String dkId = null;
-
-    public Document build(Document doc, Crypto crypto, WSSecHeader secHeader) throws Exception  {
+    public Document build(Document doc, Crypto crypto, WSSecHeader secHeader) throws WSSecurityException  {
         
         /*
          * Setup the encrypted key
@@ -120,11 +72,11 @@
         Element externRefList = encryptForExternalRef(null, parts);
         addExternalRefElement(externRefList, secHeader);
 
-        return document;
+        return doc;
     }
 
     private Vector doEncryption(Document doc, byte[] secretKey,
-            KeyInfo keyInfo, Vector references) throws Exception {
+            KeyInfo keyInfo, Vector references) throws WSSecurityException {
 
         SecretKey key = WSSecurityUtil.prepareSecretKey(this.symEncAlgo, secretKey);
         
@@ -181,190 +133,6 @@
         }
         return encDataRefs;
     }
-
-    /**
-     * @return
-     */
-    private byte[] generateNonce() throws Exception {
-        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
-        byte[] temp = new byte[16];
-        random.nextBytes(temp);
-        return temp;
-    }
-
-    /**
-     * Initialize a WSSec Derived key.
-     * 
-     * The method prepares and initializes a WSSec dereived key structure after the
-     * relevant information was set. This method also creates and initializes the
-     * derived token using the ephemeral key. After preparation references
-     * can be added and encrypted.
-     * 
-     * </p>
-     * 
-     * This method does not add any element to the security header. This must be
-     * done explicitly.
-     * 
-     * @param doc
-     *            The unsigned SOAP envelope as <code>Document</code>
-     * @param crypto
-     *            An instance of the Crypto API to handle keystore and
-     *            certificates
-     * @throws WSSecurityException
-     */
-
-    public void prepare(Document doc, Crypto crypto)
-        throws Exception {
-        
-        document = doc;
-        
-        /*
-         * Set up the ephemeral key
-         */
-        this.ephemeralKey = getEphemeralKey();
-        
-        /*
-         * Get the certificate that contains the public key for the public key
-         * algorithm that will encrypt the generated symmetric (session) key.
-         */
-        X509Certificate remoteCert = null;
-
-        X509Certificate[] certs = crypto.getCertificates(encrUser);
-        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 = WSSecurityUtil.getCipherInstance(keyEncAlgo, wssConfig
-                .getJceProviderId());
-        try {
-            cipher.init(Cipher.ENCRYPT_MODE, remoteCert);
-        } catch (InvalidKeyException e) {
-            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC,
-                    null, null, e);
-        }
-        
-        if (doDebug) {
-            log.debug("cipher blksize: " + cipher.getBlockSize()
-                    + ", symm key length: " + this.ephemeralKey.length);
-        }
-        if (cipher.getBlockSize() < this.ephemeralKey.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(this.ephemeralKey);
-        } 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);
-
-        /*
-         * Now we need to setup the EncryptedKey header block 1) create a
-         * EncryptedKey element and set a wsu:Id for it 2) Generate ds:KeyInfo
-         * element, this wraps the wsse:SecurityTokenReference 3) Create and set
-         * up the SecurityTokenReference according to the keyIdentifer parameter
-         * 4) Create the CipherValue element structure and insert the encrypted
-         * session key
-         */
-        xencEncryptedKey = createEnrcyptedKey(doc, keyEncAlgo);
-        encKeyId = "EncKeyId-" + xencEncryptedKey.hashCode();
-        xencEncryptedKey.setAttributeNS(null, "Id", encKeyId);
-
-        KeyInfo keyInfo = new KeyInfo(doc);
-
-        SecurityTokenReference secToken = new SecurityTokenReference(doc);
-
-        switch (keyIdentifierType) {
-        case WSConstants.X509_KEY_IDENTIFIER:
-            secToken.setKeyIdentifier(remoteCert);
-            break;
-
-        case WSConstants.SKI_KEY_IDENTIFIER:
-            secToken.setKeyIdentifierSKI(remoteCert, crypto);
-            break;
-
-        case WSConstants.THUMBPRINT_IDENTIFIER:
-            secToken.setKeyIdentifierThumb(remoteCert);
-            break;
-
-        case WSConstants.ISSUER_SERIAL:
-            XMLX509IssuerSerial data = new XMLX509IssuerSerial(doc, remoteCert);
-            X509Data x509Data = new X509Data(doc);
-            x509Data.add(data);
-            secToken.setX509IssuerSerial(x509Data);
-            break;
-
-        case WSConstants.BST_DIRECT_REFERENCE:
-            Reference ref = new Reference(doc);
-            ref.setURI("#" + certUri);
-            bstToken = new X509Security(doc);
-            ((X509Security) bstToken).setX509Certificate(remoteCert);
-            bstToken.setID(certUri);
-            ref.setValueType(bstToken.getValueType());
-            secToken.setReference(ref);
-            break;
-
-        default:
-            throw new WSSecurityException(WSSecurityException.FAILURE,
-                    "unsupportedKeyId");
-        }
-        
-        keyInfo.addUnknownElement(secToken.getElement());
-        WSSecurityUtil.appendChildElement(doc, xencEncryptedKey, keyInfo
-                .getElement());
-
-        Element xencCipherValue = createCipherValue(doc, xencEncryptedKey);
-        xencCipherValue.appendChild(keyText);
-
-        envelope = doc.getDocumentElement();
-        envelope.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:"
-                + WSConstants.ENC_PREFIX, WSConstants.ENC_NS);
-        
-        //Create the derived keys
-        //At this point figure out the key length accordng to teh symencAlgo
-        int offset = 0;
-        int length = WSSecurityUtil.getKeyLength(this.symEncAlgo);
-        byte[] label = ConversationConstants.DEFAULT_LABEL.getBytes("UTF-8");
-        byte[] nonce = generateNonce();
-        
-        byte[] seed = new byte[label.length + nonce.length];
-        System.arraycopy(label, 0, seed, 0, label.length);
-        System.arraycopy(nonce, 0, seed, label.length, nonce.length);
-        
-        DerivationAlgorithm algo = AlgoFactory.getInstance(ConversationConstants.DerivationAlgorithm.P_SHA_1);
-        
-        this.derivedEncrKey = algo.createKey(this.ephemeralKey, seed, offset, length);
-        
-        
-        //Add the DKTs
-        dkt = new DerivedKeyToken(document);
-        dkId = "derivedKeyId-" + dkt.hashCode();
-        
-        dkt.setLength(length);
-        dkt.setNonce(Base64.encode(nonce));
-        dkt.setOffset(offset);
-        dkt.setID(dkId);
-        //Create the SecurityTokenRef to the Encrypted Key
-        SecurityTokenReference strEncKey = new SecurityTokenReference(document);
-        Reference ref = new Reference(document);
-        ref.setURI("#" + encKeyId);
-        strEncKey.setReference(ref);
-        dkt.setSecuityTokenReference(strEncKey);
-    }
     
     /**
      * Encrypt one or more parts or elements of the message (external).
@@ -394,18 +162,18 @@
      * @throws WSSecurityException
      */
     public Element encryptForExternalRef(Element dataRef, Vector references)
-            throws Exception {
+            throws WSSecurityException {
 
         //Create the SecurityTokenRef to the DKT
         KeyInfo keyInfo = new KeyInfo(document);
         SecurityTokenReference secToken = new SecurityTokenReference(document);
         Reference ref = new Reference(document);
-        ref.setURI("#" + dkId);
+        ref.setURI("#" + dktId);
         secToken.setReference(ref);
 
         keyInfo.addUnknownElement(secToken.getElement());
 
-        Vector encDataRefs = doEncryption(document, derivedEncrKey, keyInfo,
+        Vector encDataRefs = doEncryption(document, derivedKeyBytes, keyInfo,
                 references);
         Element referenceList = dataRef;
         if (referenceList == null) {
@@ -440,105 +208,6 @@
         
     }
 
-    /**
-     * @return
-     */
-    private byte[] getEphemeralKey() throws NoSuchAlgorithmException {
-        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
-        byte[] temp = new byte[16];
-        random.nextBytes(temp);
-        return temp;
-    }
-    
-    /**
-     * Prepend the DerivedKey element to the elements already in the Security
-     * header.
-     * 
-     * The method can be called any time after <code>prepare()</code>. This
-     * allows to insert the DereivedKey element at any position in the Security
-     * header.
-     * 
-     * @param secHeader
-     *            The security header that holds the Signature element.
-     */
-    public void prependDKElementToHeader(WSSecHeader secHeader) {
-        WSSecurityUtil.prependChildElement(document, secHeader
-            .getSecurityHeader(), dkt.getElement(), false);
-    }
-    
-    
-    /**
-     * Prepend the EncryptedKey element to the elements already in the Security
-     * header.
-     * 
-     * The method can be called any time after <code>prepare()</code>. This
-     * allows to insert the EncryptedKey element at any position in the Security
-     * header.
-     * 
-     * @param secHeader
-     *            The security header that holds the Signature element.
-     */
-    public void prependToHeader(WSSecHeader secHeader) {
-        WSSecurityUtil.prependChildElement(document, secHeader
-                .getSecurityHeader(), xencEncryptedKey, false);
-    }
-
-    /**
-     * Prepend the BinarySecurityToken to the elements already in the Security
-     * header.
-     * 
-     * The method can be called any time after <code>prepare()</code>. This
-     * allows to insert the BST element at any position in the Security header.
-     * 
-     * @param secHeader
-     *            The security header that holds the BST element.
-     */
-    public void prependBSTElementToHeader(WSSecHeader secHeader) {
-        if (bstToken != null) {
-            WSSecurityUtil.prependChildElement(document, secHeader
-                    .getSecurityHeader(), bstToken.getElement(), false);
-        }
-        bstToken = null;
-    }
-    
-    /**
-     * Create DOM subtree for <code>xenc:EncryptedKey</code>
-     * 
-     * @param doc
-     *            the SOAP enevelope parent document
-     * @param keyTransportAlgo
-     *            specifies which alogrithm to use to encrypt the symmetric key
-     * @return an <code>xenc:EncryptedKey</code> element
-     */
-    public static Element createEnrcyptedKey(Document doc,
-            String keyTransportAlgo) {
-        Element encryptedKey = doc.createElementNS(WSConstants.ENC_NS,
-                WSConstants.ENC_PREFIX + ":EncryptedKey");
-
-        WSSecurityUtil.setNamespace(encryptedKey, WSConstants.ENC_NS,
-                WSConstants.ENC_PREFIX);
-        Element encryptionMethod = doc.createElementNS(WSConstants.ENC_NS,
-                WSConstants.ENC_PREFIX + ":EncryptionMethod");
-        encryptionMethod.setAttributeNS(null, "Algorithm", keyTransportAlgo);
-        WSSecurityUtil.appendChildElement(doc, encryptedKey, encryptionMethod);
-        return encryptedKey;
-    }
-    
-    public static Element createCipherValue(Document doc, Element encryptedKey) {
-        Element cipherData = doc.createElementNS(WSConstants.ENC_NS,
-                WSConstants.ENC_PREFIX + ":CipherData");
-        Element cipherValue = doc.createElementNS(WSConstants.ENC_NS,
-                WSConstants.ENC_PREFIX + ":CipherValue");
-        cipherData.appendChild(cipherValue);
-        WSSecurityUtil.appendChildElement(doc, encryptedKey, cipherData);
-        return cipherValue;
-    }
-    
-
-    public void setEncryptionUser(String user) {
-        this.encrUser = user;
-    }
-    
     public static Element createDataRefList(Document doc,
             Element referenceList, Vector encDataRefs) {
         for (int i = 0; i < encDataRefs.size(); i++) {
@@ -551,7 +220,16 @@
         return referenceList;
     }
 
+    
     public void setSymmetricEncAlgorithm(String algo) {
         symEncAlgo = algo;
     }
+
+    /**
+     * @see org.apache.ws.security.message.WSSecDerivedKeyBase#getDerivedKeyLength()
+     */
+    protected int getDerivedKeyLength() throws WSSecurityException{
+        return WSSecurityUtil.getKeyLength(this.symEncAlgo);
+    }
+    
 }

Added: webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDerivedKeyBase.java
URL: http://svn.apache.org/viewcvs/webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDerivedKeyBase.java?rev=376649&view=auto
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDerivedKeyBase.java (added)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDerivedKeyBase.java Fri Feb 10 04:42:19 2006
@@ -0,0 +1,414 @@
+/*
+ * 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 java.io.UnsupportedEncodingException;
+import java.security.InvalidKeyException;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+
+import org.apache.axis.encoding.Base64;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+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.BinarySecurity;
+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.message.token.X509Security;
+import org.apache.ws.security.util.WSSecurityUtil;
+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.Text;
+
+/**
+ * Base class for DerivedKey encryption and signature
+ *
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ * @author Davanum Srinivas (dims@yahoo.com)
+ * @author Werner Dittmann (werner@apache.org)
+ */
+public abstract class WSSecDerivedKeyBase extends WSSecBase {
+    
+    private static Log log = LogFactory.getLog(WSSecDerivedKeyBase.class.getName());
+    
+    protected Document document;
+    
+    /**
+     * Session key used as the secret in key derivation
+     */
+    protected byte[] ephemeralKey;
+    
+    /**
+     * Remote user's alias to obtain the cert to encrypt the ephemeral key 
+     */
+    protected String encrUser = null;
+    
+    /**
+     * Algorithm used to encrypt the ephemeral key
+     */
+    protected String keyEncAlgo = WSConstants.KEYTRANSPORT_RSA15;
+    
+    /**
+     * DerivedKeyToken of this builder
+     */
+    protected DerivedKeyToken dkt = null;
+    
+    /**
+     * Raw bytes of the derived key
+     */
+    protected byte[] derivedKeyBytes = null; 
+    
+    /**
+     * wsu:Id of the wsc:DerivedKeyToken
+     */
+    protected String dktId = null;
+    
+    /**
+     * xenc:EncryptedKey element
+     */
+    protected Element xencEncryptedKey = null;
+
+    /**
+     * Id value of the xenc:EncryptedKey element 
+     */
+    protected String encKeyId = null;
+    
+    /**
+     * BinarySecurityToken to be included in the case where BST_DIRECT_REFERENCE
+     * is used to refer to the asymm encryption cert
+     */
+    protected BinarySecurity bstToken = null;
+    
+    /**
+     * soap:Envelope element
+     */
+    protected Element envelope = null;
+    
+    
+    /**
+     * The derived key will change depending on the sig/encr algorithm.
+     * Therefore the child classes are expected to provide this value.
+     * @return
+     * @throws WSSecurityException
+     */
+    protected abstract int getDerivedKeyLength() throws WSSecurityException;
+   
+    
+    /**
+     * @param ephemeralKey The ephemeralKey to set.
+     */
+    public void setEphemeralKey(byte[] ephemeralKey) {
+        this.ephemeralKey = ephemeralKey;
+    }
+    
+    /**
+     * Return the raw bytes of the ephemeral key
+     * @return
+     */
+    public byte[] getEphemeralKey() {
+        return this.ephemeralKey;
+    }
+    
+    /**
+     * Sets the alias of the remote cert which is usef to encrypt the ephemeral 
+     * key
+     * @param user
+     */
+    public void setEncryptionUser(String user) {
+        this.encrUser = user;
+    }
+    
+    
+    /**
+     * Initialize a WSSec Derived key.
+     * 
+     * The method prepares and initializes a WSSec dereived key structure after the
+     * relevant information was set. This method also creates and initializes the
+     * derived token using the ephemeral key. After preparation references
+     * can be added, encrypted and signed as required.
+     * 
+     * </p>
+     * 
+     * This method does not add any element to the security header. This must be
+     * done explicitly.
+     * 
+     * @param doc
+     *            The unsigned SOAP envelope as <code>Document</code>
+     * @param crypto
+     *            An instance of the Crypto API to handle keystore and
+     *            certificates
+     * @throws WSSecurityException
+     */
+    protected void prepare(Document doc, Crypto crypto)
+        throws WSSecurityException {
+        
+        document = doc;
+        
+        /*
+         * Set up the ephemeral key
+         */
+        this.ephemeralKey = generateEphemeralKey();
+        
+        /*
+         * Get the certificate that contains the public key for the public key
+         * algorithm that will encrypt the generated symmetric (session) key.
+         */
+        X509Certificate remoteCert = null;
+
+        X509Certificate[] certs = crypto.getCertificates(encrUser);
+        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 = WSSecurityUtil.getCipherInstance(keyEncAlgo, wssConfig
+                .getJceProviderId());
+        try {
+            cipher.init(Cipher.ENCRYPT_MODE, remoteCert);
+        } catch (InvalidKeyException e) {
+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC,
+                    null, null, e);
+        }
+        
+        if (doDebug) {
+            log.debug("cipher blksize: " + cipher.getBlockSize()
+                    + ", symm key length: " + this.ephemeralKey.length);
+        }
+        if (cipher.getBlockSize() < this.ephemeralKey.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(this.ephemeralKey);
+        } 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);
+
+        /*
+         * Now we need to setup the EncryptedKey header block 1) create a
+         * EncryptedKey element and set a wsu:Id for it 2) Generate ds:KeyInfo
+         * element, this wraps the wsse:SecurityTokenReference 3) Create and set
+         * up the SecurityTokenReference according to the keyIdentifer parameter
+         * 4) Create the CipherValue element structure and insert the encrypted
+         * session key
+         */
+        xencEncryptedKey = createEnrcyptedKey(doc, keyEncAlgo);
+        encKeyId = "EncKeyId-" + xencEncryptedKey.hashCode();
+        xencEncryptedKey.setAttributeNS(null, "Id", encKeyId);
+
+        KeyInfo keyInfo = new KeyInfo(doc);
+
+        SecurityTokenReference secToken = new SecurityTokenReference(doc);
+
+        switch (keyIdentifierType) {
+        case WSConstants.X509_KEY_IDENTIFIER:
+            secToken.setKeyIdentifier(remoteCert);
+            break;
+
+        case WSConstants.SKI_KEY_IDENTIFIER:
+            secToken.setKeyIdentifierSKI(remoteCert, crypto);
+            break;
+
+        case WSConstants.THUMBPRINT_IDENTIFIER:
+            secToken.setKeyIdentifierThumb(remoteCert);
+            break;
+
+        case WSConstants.ISSUER_SERIAL:
+            XMLX509IssuerSerial data = new XMLX509IssuerSerial(doc, remoteCert);
+            X509Data x509Data = new X509Data(doc);
+            x509Data.add(data);
+            secToken.setX509IssuerSerial(x509Data);
+            break;
+
+        case WSConstants.BST_DIRECT_REFERENCE:
+            Reference ref = new Reference(doc);
+            ref.setURI("#" + certUri);
+            bstToken = new X509Security(doc);
+            ((X509Security) bstToken).setX509Certificate(remoteCert);
+            bstToken.setID(certUri);
+            ref.setValueType(bstToken.getValueType());
+            secToken.setReference(ref);
+            break;
+
+        default:
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "unsupportedKeyId");
+        }
+        
+        keyInfo.addUnknownElement(secToken.getElement());
+        WSSecurityUtil.appendChildElement(doc, xencEncryptedKey, keyInfo
+                .getElement());
+
+        Element xencCipherValue = createCipherValue(doc, xencEncryptedKey);
+        xencCipherValue.appendChild(keyText);
+
+        envelope = doc.getDocumentElement();
+        envelope.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:"
+                + WSConstants.ENC_PREFIX, WSConstants.ENC_NS);
+        
+        //Create the derived keys
+        //At this point figure out the key length accordng to teh symencAlgo
+        int offset = 0;
+        int length = this.getDerivedKeyLength();
+        byte[] label;
+        try {
+            label = ConversationConstants.DEFAULT_LABEL.getBytes("UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new WSSecurityException("UTF-8 encoding is not supported", e);
+        }
+        byte[] nonce = WSSecurityUtil.generateNonce(16);
+        
+        byte[] seed = new byte[label.length + nonce.length];
+        System.arraycopy(label, 0, seed, 0, label.length);
+        System.arraycopy(nonce, 0, seed, label.length, nonce.length);
+        
+        DerivationAlgorithm algo = AlgoFactory.getInstance(ConversationConstants.DerivationAlgorithm.P_SHA_1);
+        
+        this.derivedKeyBytes = algo.createKey(this.ephemeralKey, seed, offset, length);
+        
+        
+        //Add the DKTs
+        dkt = new DerivedKeyToken(document);
+        dktId = "derivedKeyId-" + dkt.hashCode();
+        
+        dkt.setLength(length);
+        dkt.setNonce(Base64.encode(nonce));
+        dkt.setOffset(offset);
+        dkt.setID(dktId);
+        //Create the SecurityTokenRef to the Encrypted Key
+        SecurityTokenReference strEncKey = new SecurityTokenReference(document);
+        Reference ref = new Reference(document);
+        ref.setURI("#" + encKeyId);
+        strEncKey.setReference(ref);
+        dkt.setSecuityTokenReference(strEncKey);
+    }
+
+    
+    protected byte[] generateEphemeralKey() throws WSSecurityException {
+        try {
+            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+            byte[] temp = new byte[16];
+            random.nextBytes(temp);
+            return temp;
+        } catch (Exception e) {
+            throw new WSSecurityException(
+                    "Error in creating the ephemeral key", e);
+        }
+    }
+    
+    protected Element createEnrcyptedKey(Document doc,
+            String keyTransportAlgo) {
+        Element encryptedKey = doc.createElementNS(WSConstants.ENC_NS,
+                WSConstants.ENC_PREFIX + ":EncryptedKey");
+
+        WSSecurityUtil.setNamespace(encryptedKey, WSConstants.ENC_NS,
+                WSConstants.ENC_PREFIX);
+        Element encryptionMethod = doc.createElementNS(WSConstants.ENC_NS,
+                WSConstants.ENC_PREFIX + ":EncryptionMethod");
+        encryptionMethod.setAttributeNS(null, "Algorithm", keyTransportAlgo);
+        WSSecurityUtil.appendChildElement(doc, encryptedKey, encryptionMethod);
+        return encryptedKey;
+    }
+    
+    protected Element createCipherValue(Document doc, Element encryptedKey) {
+        Element cipherData = doc.createElementNS(WSConstants.ENC_NS,
+                WSConstants.ENC_PREFIX + ":CipherData");
+        Element cipherValue = doc.createElementNS(WSConstants.ENC_NS,
+                WSConstants.ENC_PREFIX + ":CipherValue");
+        cipherData.appendChild(cipherValue);
+        WSSecurityUtil.appendChildElement(doc, encryptedKey, cipherData);
+        return cipherValue;
+    }
+    
+    /**
+     * Prepend the DerivedKey element to the elements already in the Security
+     * header.
+     * 
+     * The method can be called any time after <code>prepare()</code>. This
+     * allows to insert the DereivedKey element at any position in the Security
+     * header.
+     * 
+     * @param secHeader
+     *            The security header that holds the Signature element.
+     */
+    protected void prependDKElementToHeader(WSSecHeader secHeader) {
+        WSSecurityUtil.prependChildElement(document, secHeader
+            .getSecurityHeader(), dkt.getElement(), false);
+    }
+    
+    /**
+     * Prepend the EncryptedKey element to the elements already in the Security
+     * header.
+     * 
+     * The method can be called any time after <code>prepare()</code>. This
+     * allows to insert the EncryptedKey element at any position in the Security
+     * header.
+     * 
+     * @param secHeader
+     *            The security header that holds the Signature element.
+     */
+    protected void prependToHeader(WSSecHeader secHeader) {
+        WSSecurityUtil.prependChildElement(document, secHeader
+                .getSecurityHeader(), xencEncryptedKey, false);
+    }
+    
+    /**
+     * Prepend the BinarySecurityToken to the elements already in the Security
+     * header.
+     * 
+     * The method can be called any time after <code>prepare()</code>. This
+     * allows to insert the BST element at any position in the Security header.
+     * 
+     * @param secHeader
+     *            The security header that holds the BST element.
+     */
+    protected void prependBSTElementToHeader(WSSecHeader secHeader) {
+        if (bstToken != null) {
+            WSSecurityUtil.prependChildElement(document, secHeader
+                    .getSecurityHeader(), bstToken.getElement(), false);
+        }
+        bstToken = null;
+    }
+}

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/util/WSSecurityUtil.java
URL: http://svn.apache.org/viewcvs/webservices/wss4j/trunk/src/org/apache/ws/security/util/WSSecurityUtil.java?rev=376649&r1=376648&r2=376649&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/util/WSSecurityUtil.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/util/WSSecurityUtil.java Fri Feb 10 04:42:19 2006
@@ -46,6 +46,7 @@
 import javax.xml.namespace.QName;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
 import java.util.Vector;
 
 /**
@@ -784,6 +785,23 @@
             return 32;
         } else {
             throw new WSSecurityException(WSSecurityException.UNSUPPORTED_ALGORITHM);
+        }
+    }
+    
+    /**
+     * Generate a nonce of the given length
+     * @return
+     * @throws Exception
+     */
+    public static byte[] generateNonce(int length) throws WSSecurityException {
+        try {
+            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+            byte[] temp = new byte[length];
+            random.nextBytes(temp);
+            return temp;
+        } catch (Exception e) {
+            throw new WSSecurityException(
+                    "Error in generating nonce of length " + length, e);
         }
     }
 }

Modified: webservices/wss4j/trunk/test/wssec/TestWSSecurityNewDK.java
URL: http://svn.apache.org/viewcvs/webservices/wss4j/trunk/test/wssec/TestWSSecurityNewDK.java?rev=376649&r1=376648&r2=376649&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/TestWSSecurityNewDK.java (original)
+++ webservices/wss4j/trunk/test/wssec/TestWSSecurityNewDK.java Fri Feb 10 04:42:19 2006
@@ -44,8 +44,10 @@
 import org.apache.ws.security.WSSecurityEngine;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.message.WSSecDKSign;
 import org.apache.ws.security.message.WSSecDKSignEncrypt;
 import org.apache.ws.security.message.WSSecHeader;
+import org.apache.xml.security.signature.XMLSignature;
 import org.w3c.dom.Document;
 
 public class TestWSSecurityNewDK extends TestCase implements CallbackHandler {
@@ -134,8 +136,8 @@
         log.info("Before Encryption Triple DES....");
         Document encryptedDoc = builder.build(doc, crypto, secHeader);
         log.info("After Encryption Triple DES....");
-        String out = org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(encryptedDoc);
-        System.out.println(out);
+//        String out = org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(encryptedDoc);
+//        System.out.println(out);
         verify(doc);
     }
 
@@ -160,10 +162,32 @@
             log.debug("Encrypted message: 3DES  + DerivedKeys");
             XMLUtils.PrettyElementToWriter(encryptedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));
         }
-        String out = org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(encryptedDoc);
-        System.out.println(out);
+//        String out = org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(encryptedDoc);
+//        System.out.println(out);
         verify(doc);
-    }
+     }
+     
+     public void testSignature() throws Exception {
+         SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();
+         WSSecDKSign builder = new WSSecDKSign();
+         builder.setEncryptionUser("wss4jcert");
+         builder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
+         builder.setSignatureAlgorithm(XMLSignature.ALGO_ID_MAC_HMAC_SHA1);
+         Document doc = unsignedEnvelope.getAsDocument();
+         WSSecHeader secHeader = new WSSecHeader();
+         secHeader.insertSecurityHeader(doc);
+         log.info("Before HMAC-SHA1 signature");
+         Document signedDoc = builder.build(doc, crypto, secHeader);
+         Message signedMessage = (Message) SOAPUtil.toSOAPMessage(doc);
+         if (log.isDebugEnabled()) {
+             log.debug("Encrypted message: 3DES  + DerivedKeys");
+             XMLUtils.PrettyElementToWriter(signedMessage.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));
+         }
+//         String out = org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+//         System.out.println(out);
+         
+     }
+     
     
     /**
      * Verifies the soap envelope



---------------------------------------------------------------------
To unsubscribe, e-mail: wss4j-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: wss4j-dev-help@ws.apache.org