You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by di...@apache.org on 2003/10/14 14:05:53 UTC

cvs commit: ws-axis/contrib/wss4j/src/org/apache/ws/security/message EnvelopeIdResolver.java WSEnvelopeBuilder.java WSEnvelopeBuilder2.java

dims        2003/10/14 05:05:53

  Added:       contrib/wss4j/src/org/apache/ws/security/message
                        EnvelopeIdResolver.java WSEnvelopeBuilder.java
                        WSEnvelopeBuilder2.java
  Log:
  ******* WORK IN PROGRESS *******
  
  Initial check-in of my sandbox for ws-security related code.
  
  Revision  Changes    Path
  1.1                  ws-axis/contrib/wss4j/src/org/apache/ws/security/message/EnvelopeIdResolver.java
  
  Index: EnvelopeIdResolver.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.ws.security.message;
  
  import org.apache.ws.security.WSConstants;
  import org.apache.ws.security.util.WSSecurityUtil;
  import org.apache.xml.security.c14n.Canonicalizer;
  import org.apache.xml.security.signature.XMLSignatureInput;
  import org.apache.xml.security.utils.XMLUtils;
  import org.apache.xml.security.utils.resolver.ResourceResolverException;
  import org.apache.xml.security.utils.resolver.ResourceResolverSpi;
  import org.apache.xml.utils.URI;
  import org.apache.xpath.CachedXPathAPI;
  import org.w3c.dom.Attr;
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  import org.w3c.dom.NodeList;
  
  import java.util.Set;
  
  /**
   * XML-Security resolver that is used for resolving same-document URI like URI="#id".
   * It is desgined to only work with SOAPEnvelopes.
   * <p>
   * @author  Davanum Srinivas (dims@yahoo.com).
   */
  public class EnvelopeIdResolver extends ResourceResolverSpi {
      private static EnvelopeIdResolver resolver = null;
  
      /**
       * Singleton instance of the resolver.
       * <p>
       * @return   
       */
      public synchronized static ResourceResolverSpi getInstance() {
          if (resolver == null) {
              resolver = new EnvelopeIdResolver();
          }
  
          return resolver;
      }
  
      /**
       * This is the workhorse method used to resolve resources.
       * <p>
       * @param   uri                         
       * @param   BaseURI                     
       * @return                              
       * @throws  ResourceResolverException  
       */
      public XMLSignatureInput engineResolve(Attr uri, String BaseURI) throws ResourceResolverException {
          String uriNodeValue = uri.getNodeValue();
          NodeList resultNodes = null;
          Document doc = uri.getOwnerDocument();
  
          // Xalan fix for catching all namespaces
          XMLUtils.circumventBug2650(doc);
  
          CachedXPathAPI cXPathAPI = new CachedXPathAPI();
  
          /*
           * URI="#chapter1"
           * Identifies a node-set containing the element with ID attribute
           * value 'chapter1' of the XML resource containing the signature.
           * XML Signature (and its applications) modify this node-set to
           * include the element plus all descendents including namespaces and
           * attributes -- but not comments.
           */
          String id = uriNodeValue.substring(1);
          Element selectedElem = WSSecurityUtil.findBodyElement(doc);
  
          if (selectedElem == null) {
              throw new ResourceResolverException("generic.EmptyMessage", new Object[]{"Body element not found"}, uri, BaseURI);
          }
  
          String cId = selectedElem.getAttributeNS(WSConstants.WSU_NS, "Id");
  
          if ((cId == null) || (cId.length() == 0)) {
              cId = selectedElem.getAttributeNS(WSConstants.SOAP_SEC_NS, "id");
          }
  
          if (!id.equals(cId)) {
              selectedElem = WSSecurityUtil.getElementById(doc, uriNodeValue);
  
              if (selectedElem != null) {
                  cId = selectedElem.getAttributeNS(WSConstants.WSU_NS, "Id");
              }
          }
  
          if (!id.equals(cId)) {
              throw new ResourceResolverException("generic.EmptyMessage", new Object[]{"Id not found"}, uri, BaseURI);
          }
  
          try {
              resultNodes = cXPathAPI.selectNodeList(selectedElem, Canonicalizer.XPATH_C14N_OMIT_COMMENTS_SINGLE_NODE);
          } catch (javax.xml.transform.TransformerException ex) {
              throw new ResourceResolverException("generic.EmptyMessage", ex, uri, BaseURI);
          }
  
          Set resultSet = XMLUtils.convertNodelistToSet(resultNodes);
          XMLSignatureInput result = new XMLSignatureInput(resultSet, cXPathAPI);
          result.setMIMEType("text/xml");
  
          try {
              URI uriNew = new URI(new URI(BaseURI), uri.getNodeValue());
              result.setSourceURI(uriNew.toString());
          } catch (URI.MalformedURIException ex) {
              result.setSourceURI(BaseURI);
          }
  
          return result;
      }
  
      /**
       * This method helps the ResourceResolver to decide whether a
       * ResourceResolverSpi is able to perform the requested action.
       * <p>
       * @param   uri       
       * @param   BaseURI   
       * @return            
       */
      public boolean engineCanResolve(Attr uri, String BaseURI) {
          if (uri == null) {
              return false;
          }
  
          String uriNodeValue = uri.getNodeValue();
  
          return uriNodeValue.startsWith("#");
      }
  }
  
  
  
  1.1                  ws-axis/contrib/wss4j/src/org/apache/ws/security/message/WSEnvelopeBuilder.java
  
  Index: WSEnvelopeBuilder.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.ws.security.message;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.ws.security.WSConstants;
  import org.apache.ws.security.components.crypto.Crypto;
  import org.apache.ws.security.components.crypto.CryptoFactory;
  import org.apache.ws.security.message.token.*;
  import org.apache.ws.security.util.AxisUtil;
  import org.apache.ws.security.util.WSSecurityUtil;
  import org.apache.xml.security.c14n.Canonicalizer;
  import org.apache.xml.security.keys.KeyInfo;
  import org.apache.xml.security.signature.XMLSignature;
  import org.apache.xml.security.transforms.Transforms;
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  import org.w3c.dom.Node;
  
  import javax.xml.soap.*;
  import java.security.cert.X509Certificate;
  import java.util.Iterator;
  
  /**
   * Builds X509 WS-Security SOAP Envelopes.
   * <p>
   * @author  Davanum Srinivas (dims@yahoo.com).
   */
  public class WSEnvelopeBuilder {
      private static Log log = LogFactory.getLog(WSEnvelopeBuilder.class.getName());
      protected String actor = null;
      protected boolean useSingleCert = true;
      protected String user = null;
      protected String password = null;
  
      /** Constructor. */
      public WSEnvelopeBuilder() {
      }
  
      /**
       * Constructor.
       * <p>
       * @param  actor   
       */
      public WSEnvelopeBuilder(String actor) {
          this.actor = actor;
      }
  
      /**
       * set the single cert flag.
       * <p>
       * @param  useSingleCert   
       */
      public void setUseSingleCertificate(boolean useSingleCert) {
          this.useSingleCert = useSingleCert;
      }
  
      /**
       * Get the single cert flag.
       * <p>
       * @return   
       */
      public boolean isUseSingleCertificate() {
          return this.useSingleCert;
      }
  
      /**
       * add a body id.
       * <p>
       * @param   doc         
       * @return              
       * @throws  Exception  
       */
      protected String setBodyID(Document doc) throws Exception {
          Element bodyElement = WSSecurityUtil.findBodyElement(doc);
  
          if (bodyElement == null) {
              throw new Exception("Element node not found");
          }
  
          String id = bodyElement.getAttributeNS(WSConstants.WSU_NS, "Id");
  
          if ((id == null) || (id.length() == 0)) {
              id = "digestSource";
  
              String prefix = WSSecurityUtil.setNamespace(bodyElement, WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
              bodyElement.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);
          }
  
          return id;
      }
  
      /**
       * add a security header if one does not exist.
       * <p>
       * @param   env             
       * @return                  
       * @throws  SOAPException  
       */
      protected SOAPHeaderElement insertSecurityHeader(SOAPEnvelope env) throws SOAPException {
          SOAPHeader header = env.getHeader();
  
          if (header == null) {
              header = env.addHeader();
          }
  
          Iterator headerElements = header.examineHeaderElements(actor);
          SOAPHeaderElement he;
  
          while (headerElements.hasNext()) {
              he = (SOAPHeaderElement) headerElements.next();
  
              Name nm = he.getElementName();
  
              // find the ws-security header
              if (nm.getLocalName().equalsIgnoreCase(WSConstants.WSSE_LN) && nm.getURI().equalsIgnoreCase(WSConstants.WSSE_NS)) {
                  return he;
              }
          }
  
          // if no ws-security header add one
          Name headerName = env.createName(WSConstants.WSSE_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
          he = header.addHeaderElement(headerName);
          he.setActor(actor);
  
          return he;
      }
  
      /**
       * insert element into security header.
       * <p>
       * @param   doc         
       * @param   elem        
       * @throws  Exception  
       */
      protected void insertIntoSecurityHeader(Document doc, Element elem) throws Exception {
          Element wsSecHeaderElement = WSSecurityUtil.getSecurityHeader(doc, actor);
  
          if (wsSecHeaderElement == null) {
              throw new Exception("No header found");
          }
  
          Node firstChild = wsSecHeaderElement.getFirstChild();
  
          if (firstChild == null) {
              wsSecHeaderElement.appendChild(elem);
          } else {
              wsSecHeaderElement.insertBefore(elem, firstChild);
          }
      }
  
      /**
       * Set the user name token info.
       * <p>
       * @param  user       
       * @param  password   
       */
      public void setUserInfo(String user, String password) {
          this.user = user;
          this.password = password;
      }
  
      /**
       * builds a signed soap envelope.
       * <p>
       * @param   envelope    
       * @return              
       * @throws  Exception  
       */
      public SOAPEnvelope build(SOAPEnvelope envelope) throws Exception {
          log.debug("Beginning signing...");
  
          Crypto crypto = CryptoFactory.getInstance();
  
          if (crypto == null) {
              throw new Exception("no credentials");
          }
  
          insertSecurityHeader(envelope);
  
          Document doc = AxisUtil.toDocument(envelope);
  
          // Set the id of the elements to be used as digest source
          String id = setBodyID(doc);
          String uri = id + (useSingleCert ? "X509Token" : "PKIToken");
          XMLSignature sig = null;
  
          if (user == null) {
              sig = new XMLSignature(doc, null, XMLSignature.ALGO_ID_SIGNATURE_RSA, Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
          } else {
              sig = new XMLSignature(doc, null, XMLSignature.ALGO_ID_MAC_HMAC_SHA1, Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
          }
  
          Transforms transforms = new Transforms(doc);
          transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
          sig.addResourceResolver(EnvelopeIdResolver.getInstance());
          sig.addDocument("#" + id, transforms);
  
          Reference ref = new Reference(doc);
          ref.setURI("#" + uri);
  
          SecurityTokenReference secRef = new SecurityTokenReference(doc);
          secRef.setReference(ref);
  
          KeyInfo info = sig.getKeyInfo();
          info.addUnknownElement(secRef.getElement());
  
          if (user == null) {
              X509Certificate[] certs = crypto.getCertificates();
              BinarySecurity token = null;
  
              if (!useSingleCert) {
                  token = new PKIPathSecurity(doc);
                  ((PKIPathSecurity) token).setX509Certificates(certs, true);
              } else {
                  token = new X509Security(doc);
                  ((X509Security) token).setX509Certificate(certs[0]);
              }
  
              token.setID(uri);
              insertIntoSecurityHeader(doc, sig.getElement());
              sig.sign(crypto.getPrivateKey());
              insertIntoSecurityHeader(doc, token.getElement());
          } else if (user != null) {
              UsernameToken token2 = new UsernameToken(doc);
              token2.setName(this.user);
              token2.setPassword(this.password);
              token2.setID(uri);
              insertIntoSecurityHeader(doc, sig.getElement());
              sig.sign(sig.createSecretKey(token2.getSecretKey()));
              insertIntoSecurityHeader(doc, token2.getElement());
          }
  
          log.debug("Signing complete.");
  
          return AxisUtil.toSOAPMessage(doc).getSOAPPart().getEnvelope();
      }
  }
  
  
  
  1.1                  ws-axis/contrib/wss4j/src/org/apache/ws/security/message/WSEnvelopeBuilder2.java
  
  Index: WSEnvelopeBuilder2.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.ws.security.message;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.ws.security.WSConstants;
  import org.apache.ws.security.components.crypto.Crypto;
  import org.apache.ws.security.components.crypto.CryptoFactory;
  import org.apache.ws.security.util.AxisUtil;
  import org.apache.ws.security.util.WSSecurityUtil;
  import org.apache.xml.security.encryption.XMLCipher;
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  
  import javax.crypto.Cipher;
  import javax.crypto.KeyGenerator;
  import javax.crypto.SecretKey;
  import javax.xml.soap.SOAPEnvelope;
  import java.security.cert.X509Certificate;
  
  /**
   * Builds X509 WS-Security SOAP Envelopes.
   * <p>
   * @author  Davanum Srinivas (dims@yahoo.com).
   */
  public class WSEnvelopeBuilder2 extends WSEnvelopeBuilder {
      private static Log log = LogFactory.getLog(WSEnvelopeBuilder2.class.getName());
  
      /** Constructor. */
      public WSEnvelopeBuilder2() {
      }
  
      /**
       * Constructor.
       * <p>
       * @param  actor   
       */
      public WSEnvelopeBuilder2(String actor) {
          this.actor = actor;
      }
  
      /**
       * builds a signed soap envelope.
       * <p>
       * @param   soapEnvelope          
       * @return              
       * @throws  Exception  
       */
      public SOAPEnvelope build(SOAPEnvelope soapEnvelope) throws Exception {
          log.debug("Beginning Encryption...");
  
          Document doc = AxisUtil.toDocument(soapEnvelope);
          Element envelope = doc.getDocumentElement();
  
          envelope.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:" + WSConstants.ENC_PREFIX, WSConstants.ENC_NS);
  
          Element nsContext = WSSecurityUtil.createNamespaceContext(doc);
  
          Element body = (Element) WSSecurityUtil.selectSingleNode(envelope, "env:Body", nsContext);
          XMLCipher xmlCipher = XMLCipher.getInstance(WSConstants.ENC_NS + "tripledes-cbc");
          KeyGenerator keyGen = KeyGenerator.getInstance("DESede");
          SecretKey symmetricKey = keyGen.generateKey();
          xmlCipher.init(XMLCipher.ENCRYPT_MODE, symmetricKey);
  
          Element firstChild = (Element) WSSecurityUtil.selectSingleNode(body, "*", nsContext);
          xmlCipher.doFinal(doc, firstChild);
  
          Element xencEncryptedData = (Element) WSSecurityUtil.selectSingleNode(body, "xenc:EncryptedData", nsContext);
          String xencEncryptedDataId = "enc1";
          String xencEncryptedDataRef = "#" + xencEncryptedDataId;
  
          xencEncryptedData.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsu", WSConstants.WSU_NS);
          xencEncryptedData.setAttributeNS(WSConstants.WSU_NS, "wsu:Id", xencEncryptedDataId);
  
          Element wsseSecurity = WSSecurityUtil.findWsseSecurityHeaderBlock(doc, envelope, true);
          Element xencEncryptedKey = createSubtreeXencEncryptedKey(doc, xencEncryptedDataRef);
          WSSecurityUtil.prependChildElement(doc, wsseSecurity, xencEncryptedKey, true);
  
          Element wsseKeyIdentifier = (Element) WSSecurityUtil.selectSingleNode(xencEncryptedKey, "wsse:KeyIdentifier", nsContext);
          X509Certificate remoteCert = null;
          Crypto crypto = CryptoFactory.getInstance();
  
          if (crypto == null) {
              throw new Exception("no credentials");
          }
  
          remoteCert = crypto.getCertificates()[0];
  
          byte encodedCert[] = remoteCert.getEncoded();
          org.w3c.dom.Text certText = WSSecurityUtil.createBase64EncodedTextNode(doc, encodedCert);
          wsseKeyIdentifier.appendChild(certText);
  
          Cipher cipher = Cipher.getInstance("RSA");
          cipher.init(Cipher.ENCRYPT_MODE, remoteCert);
  
          byte[] encryptedKey = cipher.doFinal(symmetricKey.getEncoded());
          org.w3c.dom.Text keyText = WSSecurityUtil.createBase64EncodedTextNode(doc, encryptedKey);
          Element xencCipherValue = (Element) WSSecurityUtil.selectSingleNode(xencEncryptedKey, "xenc:CipherData/xenc:CipherValue", nsContext);
          xencCipherValue.appendChild(keyText);
          log.debug("Encryption complete.");
  
          return AxisUtil.toSOAPMessage(doc).getSOAPPart().getEnvelope();
      }
  
      /**
       * create dom subtree
       * <p>
       * @param   doc                
       * @param   dataReferenceUri   
       * @return                     
       */
      public static Element createSubtreeXencEncryptedKey(Document doc, String dataReferenceUri) {
          Element encryptedKey = doc.createElementNS(WSConstants.ENC_NS, "xenc:EncryptedKey");
          encryptedKey.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:xenc", WSConstants.ENC_NS);
          Element encryptionMethod = doc.createElementNS(WSConstants.ENC_NS, "xenc:EncryptionMethod");
          encryptionMethod.setAttributeNS(null, "Algorithm", WSConstants.ENC_NS + "rsa-1_5");
          WSSecurityUtil.appendChildElement(doc, encryptedKey, encryptionMethod);
  
          Element keyIdentifier = doc.createElementNS(WSConstants.WSSE_NS, "wsse:KeyIdentifier");
          keyIdentifier.setAttributeNS(null, "ValueType", "wsse:X509v3");
          keyIdentifier.setAttributeNS(null, "EncodingType", "wsse:Base64Binary");
          WSSecurityUtil.appendChildElement(doc, encryptedKey, keyIdentifier);
  
          Element cipherData = doc.createElementNS(WSConstants.ENC_NS, "xenc:CipherData");
          Element cipherValue = doc.createElementNS(WSConstants.ENC_NS, "xenc:CipherValue");
          cipherData.appendChild(cipherValue);
          WSSecurityUtil.appendChildElement(doc, encryptedKey, cipherData);
  
          Element referenceList = doc.createElementNS(WSConstants.ENC_NS, "xenc:ReferenceList");
          Element dataReference = doc.createElementNS(WSConstants.ENC_NS, "xenc:DataReference");
          dataReference.setAttributeNS(null, "URI", dataReferenceUri);
          referenceList.appendChild(dataReference);
          WSSecurityUtil.appendChildElement(doc, encryptedKey, referenceList);
  
          return encryptedKey;
      }
  }