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 we...@apache.org on 2005/09/25 15:29:36 UTC

svn commit: r291403 - in /webservices/wss4j/trunk/src/org/apache/ws/security: message/EnvelopeIdResolver.java transform/STRTransform.java

Author: werner
Date: Sun Sep 25 06:29:29 2005
New Revision: 291403

URL: http://svn.apache.org/viewcvs?rev=291403&view=rev
Log:
Do quite some reworking in STRTransform. Due to this we better use
the XML-SEC library, no more "circumventBug2650" calls, etc.

Modified:
    webservices/wss4j/trunk/src/org/apache/ws/security/message/EnvelopeIdResolver.java
    webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/message/EnvelopeIdResolver.java
URL: http://svn.apache.org/viewcvs/webservices/wss4j/trunk/src/org/apache/ws/security/message/EnvelopeIdResolver.java?rev=291403&r1=291402&r2=291403&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/message/EnvelopeIdResolver.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/message/EnvelopeIdResolver.java Sun Sep 25 06:29:29 2005
@@ -89,9 +89,6 @@
 
         Document doc = uri.getOwnerDocument();
 
-        // Xalan fix for catching all namespaces
-        XMLUtils.circumventBug2650(doc);
-
         /*
          * URI="#chapter1"
          * Identifies a node-set containing the element with ID attribute
@@ -136,9 +133,7 @@
             }
         }
 
-        Set resultSet = dereferenceSameDocumentURI(selectedElem);
-        XMLSignatureInput result = new XMLSignatureInput(resultSet);
-//        XMLSignatureInput result = new XMLSignatureInput(selectedElem);
+        XMLSignatureInput result = new XMLSignatureInput(selectedElem);
         result.setMIMEType("text/xml");
         try {
             URI uriNew = new URI(new URI(BaseURI), uri.getNodeValue());

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java
URL: http://svn.apache.org/viewcvs/webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java?rev=291403&r1=291402&r2=291403&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java Sun Sep 25 06:29:29 2005
@@ -39,6 +39,7 @@
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.w3c.dom.Text;
+import org.w3c.dom.DOMImplementation;
 import org.xml.sax.SAXException;
 
 import javax.xml.parsers.DocumentBuilder;
@@ -52,7 +53,7 @@
 
 /**
  * Class STRTransform
- *
+ * 
  * @author Werner Dittmann (Werner.Dittmann@siemens.com)
  * @version 1.0
  */
@@ -61,12 +62,16 @@
     /**
      * Field implementedTransformURI
      */
-    public static final String implementedTransformURI =
-            "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#STR-Transform";
+    public static final String implementedTransformURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#STR-Transform";
 
     private static Log log = LogFactory.getLog(STRTransform.class.getName());
+
     private static boolean doDebug = false;
 
+    private static String FAKE_NS = "urn:X";
+
+    private static String XMLNS = "xmlns=";
+
     private WSDocInfo wsDocInfo = null;
 
     public boolean wantsOctetStream() {
@@ -94,15 +99,14 @@
 
     /**
      * Method enginePerformTransform
-     *
+     * 
      * @param input
      * @throws CanonicalizationException
      * @throws InvalidCanonicalizerException
      */
     protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input)
-            throws IOException,
-                   CanonicalizationException,
-                   InvalidCanonicalizerException {
+            throws IOException, CanonicalizationException,
+            InvalidCanonicalizerException {
 
         doDebug = log.isDebugEnabled();
 
@@ -113,8 +117,7 @@
         try {
 
             /*
-             * Get the main document, that is the complete SOAP
-             * request document
+             * Get the main document, that is the complete SOAP request document
              */
             Document thisDoc = this._transformObject.getDocument();
             int docHash = thisDoc.hashCode();
@@ -133,145 +136,118 @@
             }
 
             /*
-             * According to the OASIS WS Specification
-             * "Web Services Security: SOAP Message Security 1.0"
-             * Monday, 19 January 2004, chapter 8.3 describes that
-             * the input node set must be processed bythe c14n that
-             * is specified in the argument element of the STRTransform
+             * According to the OASIS WS Specification "Web Services Security:
+             * SOAP Message Security 1.0" Monday, 19 January 2004, chapter 8.3
+             * describes that the input node set must be processed bythe c14n
+             * that is specified in the argument element of the STRTransform
              * element.
-             *
-             * First step: Get the required c14n argument. After that, get
-             * the c14n, feed the node set into c14n and get back the byte[].
-             * The byte[] contains the XML doc part to be
-             * signed or verified. Then reparse the byte[] to get the DOM.
+             * 
+             * First step: Get the required c14n argument and get the specified
+             * Canonicalizer
              */
 
             String canonAlgo = null;
             if (this._transformObject.length(WSConstants.WSSE_NS,
                     "TransformationParameters") == 1) {
-                Element tmpE = XMLUtils.selectNode(
-                        this._transformObject.getElement().getFirstChild(),
-                        WSConstants.WSSE_NS, "TransformationParameters", 0);
+                Element tmpE = XMLUtils.selectNode(this._transformObject
+                        .getElement().getFirstChild(), WSConstants.WSSE_NS,
+                        "TransformationParameters", 0);
                 Element canonElem = (Element) WSSecurityUtil.getDirectChild(
-                    tmpE, "CanonicalizationMethod", WSConstants.SIG_NS);
+                        tmpE, "CanonicalizationMethod", WSConstants.SIG_NS);
                 canonAlgo = canonElem.getAttribute("Algorithm");
                 if (doDebug) {
                     log.debug("CanonAlgo: " + canonAlgo);
                 }
             }
             Canonicalizer canon = Canonicalizer.getInstance(canonAlgo);
-//            byte buf[] = canon.canonicalizeXPathNodeSet(input.getNodeSet());
-            byte buf[] = input.getBytes();
-
-            ByteArrayOutputStream bos = new ByteArrayOutputStream(buf.length);
-            bos.write(buf, 0, buf.length);
 
+            ByteArrayOutputStream bos = null;
+            byte[] buf = null;
             if (doDebug) {
+                buf = input.getBytes();
+                bos = new ByteArrayOutputStream(buf.length);
+                bos.write(buf, 0, buf.length);
                 log.debug("canon bos: " + bos.toString());
             }
 
-            DocumentBuilderFactory dfactory = DocumentBuilderFactory
-                    .newInstance();
-            dfactory.setValidating(false);
-            dfactory.setNamespaceAware(true);
-
-            DocumentBuilder db = dfactory.newDocumentBuilder();
-
-            Document doc = db
-                    .parse(new ByteArrayInputStream(bos.toByteArray()));
-
             /*
-             * Second step: find the STR element inside the resulting XML doc,
-             * check if STR contains some reference to an security token.
+             * Get the input (node) to transform. Currently we support only
+             * an Element as input format. If other formats are required
+             * we must get it as bytes and probably reparse it into a DOM
+             * tree (How to work with nodesets? how to select the right node
+             * from a nodeset?) 
              */
-
-            NodeList nodeList =
-                    doc.getElementsByTagNameNS(WSConstants.WSSE_NS,
-                            "SecurityTokenReference");
-
             Element str = null;
-            Element tmpEl = (Element) nodeList.item(0);
-            if (doDebug) {
-                log.debug("STR: " + tmpEl.toString());
+            if (input.isElement()) {
+                str = (Element) input.getSubNode();
+            } else {
+                throw (new CanonicalizationException(
+                        "Wrong input format - only element input supported"));
             }
-            /*
-             * Third and forth step are performed by derefenceSTR()
-             */
-            SecurityTokenReference secRef = new SecurityTokenReference(tmpEl);
 
-            str = dereferenceSTR(thisDoc, secRef);
+            if (doDebug) {
+                log.debug("STR: " + str.toString());
+            }
             /*
-             * Keep in mind: the returned element belong to "thisDoc", thus
-             * import it to "doc" before replacing it.
-             *
-             * Fifth step: replace the STR with the above created/copied BST, feed
-             * this result in the specified c14n method and return this to
-             * the caller.
-             *
+             * The element to transform MUST be a SecurityTokenReference element.
              */
-            str = (Element) doc.importNode(str, true);
-
-            Node parent = tmpEl.getParentNode(); // point to document node
-
-
+            SecurityTokenReference secRef = new SecurityTokenReference(str);
             /*
-             * Alert: Hacks ahead
-             *
-             * TODO: Rework theses hacks after c14n was updated.
+             * Third and forth step are performed by derefenceSTR()
              */
-
-            /*
-             * HACK 1:
-             * Create a top level fake element with a defined default namespace
-             * setting (urn:X). Replace the STR node with this fake element that
-             * is now the top level element. Append our result element to the
-             * fake element, then call c14n. This forces the c14n to insert
-             * xmlns="" if necessary. However, before we handover the result we
-             * have to remove the fake element. See string buffer operation
-             * below.
-             */
-//          parent.replaceChild(str, tmpEl); // replace STR with new node
-
-            Element tmpEl1 = doc.createElement("temp");
-            tmpEl1.setAttributeNS(WSConstants.XMLNS_NS, "xmlns", "urn:X");
-            parent.replaceChild(tmpEl1, tmpEl); // replace STR with new node
-            tmpEl1.appendChild(str);
-            // End of HACK 1
-
-            // XMLUtils.circumventBug2650(doc); // No longer needed???
-
+            Element dereferencedToken = dereferenceSTR(thisDoc, secRef);
             /*
              * C14n with specified algorithm. According to WSS Specification.
              */
-            buf = canon.canonicalizeSubtree(doc, "#default");
-
-            // If the problem with c14n method is solved then just do:
-            bos = new ByteArrayOutputStream(buf.length);
-            bos.write(buf, 0, buf.length);
-
+            buf = canon.canonicalizeSubtree(dereferencedToken, "#default");
             if (doDebug) {
+                bos = new ByteArrayOutputStream(buf.length);
+                bos.write(buf, 0, buf.length);
                 log.debug("after c14n: " + bos.toString());
             }
 
-//            return new XMLSignatureInput(buf);
+
+             /*
+             * Alert: Hacks ahead
+             * According to WSS spec an Apex node must contain a default
+             * namespace. If none is availabe in the first node of the
+             * c14n output (this is the apex element) then we do some
+             * editing to insert an empty default namespace
+             * 
+             * TODO: Rework theses hacks after c14n was updated and can be
+             * instructed to insert empty default namespace if required
+             */            
+            // If the problem with c14n method is solved then just do:
+            // return new XMLSignatureInput(buf);
+
+            // start of HACK
+            StringBuffer bf = new StringBuffer(new String(buf));
 
             /*
-             * HACK 2
+             * Find start and end of first element <....>, this is the Apex node
              */
-
+            int lt = bf.indexOf("<");
+            int gt = bf.indexOf(">");
             /*
-             * Here we delete the previously inserted fake element from the
-             * serialized XML.
+             * Lookup the default namespace
              */
-            StringBuffer bf = new StringBuffer(bos.toString());
-            String bf1 = bf.substring("<temp xmlns=\"urn:X\">".length(), bf.length() - "</temp>".length());
-
+            int idx = bf.indexOf(XMLNS);
+            /*
+             * If none found or if it is outside of this (Apex) element look for
+             * first blank in, insert default namespace there (this is the
+             * correct place according to c14n specification)
+             */
+            if (idx < 0 || idx > gt) {
+                idx = bf.indexOf(" ");
+                bf.insert(idx + 1, "xmlns=\"\" ");
+            }
+            String bf1 = bf.toString();
             if (doDebug) {
                 log.debug("last result: ");
-                log.debug(bf1.toString());
+                log.debug(bf1);
             }
             return new XMLSignatureInput(bf1.getBytes());
-            // End of HACK 2
+            // End of HACK
 
         } catch (IOException ex) {
             throw new CanonicalizationException("empty", ex);
@@ -292,29 +268,23 @@
             throws Exception {
 
         /*
-         * Third step: locate the security token referenced by the STR
-         * element. Either the Token is contained in the document as a
+         * Third step: locate the security token referenced by the STR element.
+         * Either the Token is contained in the document as a
          * BinarySecurityToken or stored in some key storage.
-         *
+         * 
          * Forth step: after security token was located, prepare it. If its
          * reference via a direct reference, i.e. a relative URI that references
          * the BST directly in the message then just return that element.
-         * Otherwise wrap the located token in a newly created BST element
-         * as described in WSS Specification.
-         *
-         * Note: every element (also newly created elements) belong to the
-         * document defined by the doc parameter. This is the main SOAP document
-         * (thisDoc) and _not_ the document part that is to be signed/verified. Thus
-         * the caller must import the returned element into the document
-         * part that is signed/verified.
-         *
+         * Otherwise wrap the located token in a newly created BST element as
+         * described in WSS Specification.
+         * 
          */
         Element tokElement = null;
 
         /*
-         * First case: direct reference, according to chap 7.2 of OASIS
-         * WS specification (main document). Only in this case return
-         * a true reference to the BST. Copying is done by the caller.
+         * First case: direct reference, according to chap 7.2 of OASIS WS
+         * specification (main document). Only in this case return a true
+         * reference to the BST. Copying is done by the caller.
          */
         if (secRef.containsReference()) {
             if (doDebug) {
@@ -326,72 +296,56 @@
             }
         }
         /*
-         * second case: IssuerSerial, first try to get embedded
-         * certificate, if that fails, lookup in keystore, wrap
-         * in BST according to specification
+         * second case: IssuerSerial, lookup in keystore, wrap in BST according
+         * to specification
          */
         else if (secRef.containsX509Data() || secRef.containsX509IssuerSerial()) {
             if (doDebug) {
                 log.debug("STR: IssuerSerial");
             }
             X509Certificate cert = null;
-            X509Security x509token = null;
-            // Disable check for embedded, always get from store (comment from Merlin,
-            // Betrust)
-            // x509token = secRef.getEmbeddedTokenFromIS(doc, wsDocInfo.getCrypto());
-            if (x509token != null) {
-                cert = x509token.getX509Certificate(wsDocInfo.getCrypto());
-            } else {
-                X509Certificate[] certs = secRef.getX509IssuerSerial(wsDocInfo.getCrypto());
-                if (certs == null || certs.length == 0 || certs[0] == null) {
-                    throw new CanonicalizationException("empty");
-                }
-                cert = certs[0];
+            X509Certificate[] certs = secRef.getX509IssuerSerial(wsDocInfo
+                    .getCrypto());
+            if (certs == null || certs.length == 0 || certs[0] == null) {
+                throw new CanonicalizationException("empty");
             }
-            tokElement = createBST(doc, cert, secRef.getElement());
+            cert = certs[0];
+            tokElement = createBSTX509(doc, cert, secRef.getElement());
         }
         /*
-         * third case: KeyIdentifier, must be SKI, first try to get embedded
-         * certificate, if that fails, lookup in keystore, wrap
-         * in BST according to specification. No other KeyIdentifier
-         * type handled here - just SKI
+         * third case: KeyIdentifier, must be SKI, lookup in keystore, wrap in
+         * BST according to specification. No other KeyIdentifier type handled
+         * here - just SKI
          */
         else if (secRef.containsKeyIdentifier()) {
             if (doDebug) {
                 log.debug("STR: KeyIdentifier");
             }
             X509Certificate cert = null;
-            X509Security x509token = null;
-            // Disable check for embedded, always get from store (comment from Merlin,
-            // Betrust)
-            // x509token = secRef.getEmbeddedTokenFromSKI(doc, wsDocInfo.getCrypto());
-            if (x509token != null) {
-                cert = x509token.getX509Certificate(wsDocInfo.getCrypto());
-            } else {
-                X509Certificate[] certs = secRef.getKeyIdentifier(wsDocInfo.getCrypto());
-                if (certs == null || certs.length == 0 || certs[0] == null) {
-                    throw new CanonicalizationException("empty");
-                }
-                cert = certs[0];
+            X509Certificate[] certs = secRef.getKeyIdentifier(wsDocInfo
+                    .getCrypto());
+            if (certs == null || certs.length == 0 || certs[0] == null) {
+                throw new CanonicalizationException("empty");
             }
-            tokElement = createBST(doc, cert, secRef.getElement());
+            cert = certs[0];
+            tokElement = createBSTX509(doc, cert, secRef.getElement());
         }
         return (Element) tokElement;
     }
 
-    private Element createBST(Document doc,
-                              X509Certificate cert,
-                              Element secRefE)
-            throws Exception {
+    private Element createBSTX509(Document doc, X509Certificate cert,
+            Element secRefE) throws Exception {
+
         byte data[] = cert.getEncoded();
-        String prefix = WSSecurityUtil.getPrefixNS(WSConstants.WSSE_NS, secRefE);
-        Element elem =
-                doc.createElementNS(WSConstants.WSSE_NS,
-                        prefix + ":BinarySecurityToken");
+        String prefix = WSSecurityUtil
+                .getPrefixNS(WSConstants.WSSE_NS, secRefE);
+        Element elem = doc.createElementNS(WSConstants.WSSE_NS, prefix
+                + ":BinarySecurityToken");
         WSSecurityUtil.setNamespace(elem, WSConstants.WSSE_NS, prefix);
-        elem.setAttributeNS(WSConstants.XMLNS_NS, "xmlns", "");
+        // elem.setAttributeNS(WSConstants.XMLNS_NS, "xmlns", "");
         elem.setAttributeNS(null, "ValueType", X509Security.getType());
-        Text certText = doc.createTextNode(Base64.encode(data));  // no line wrap
+        Text certText = doc.createTextNode(Base64.encode(data)); // no lne
+                                                                    // wrap
         elem.appendChild(certText);
         return elem;
     }



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