All,

I observed that there were some TODO items in XMLCipher.java. Some of them were related to martialing of KeyInfo and ReferenceList. I have prepared (please find attached) a patch for these. The KeyInfo martialing I thought was already achieved (KeyInfo.getElement()), and for ReferenceList I did the following --

1) Converted ReferenceList class into an interface.
2) Added implementation for it (containing a toElement() method) inside the private Factory class.


This change results in a uniformity across the implementation. ReferenceList is now being handled like other encryption elements. Please let me know if there are any issues with this patch.

Regards,
Vishal
/*
 * 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.xml.security.encryption;


import java.util.Iterator;
import org.w3c.dom.Element;


/**
 * A wrapper for a pointer from a key value of an <code>EncryptedKey</code> to
 * items encrypted by that key value (<code>EncryptedData</code> or
 * <code>EncryptedKey</code> elements).
 * <p>
 * It is defined as follows:
 * <xmp>
 * <complexType name='ReferenceType'>
 *     <sequence>
 *         <any namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
 *     </sequence>
 *     <attribute name='URI' type='anyURI' use='required'/>
 * </complexType>
 * </xmp>
 *
 * @author Axl Mattheus
 * @see ReferenceList
 */
public interface Reference {
    /**
     * Returns a <code>URI</code> that points to an <code>Element</code> that
     * were encrypted using the key defined in the enclosing
     * <code>EncryptedKey</code> element.
     *
     * @return an Uniform Resource Identifier that qualifies an
     *   <code>EncryptedType</code>.
     */
    String getURI();

    /**
     * Sets a <code>URI</code> that points to an <code>Element</code> that
     * were encrypted using the key defined in the enclosing
     * <code>EncryptedKey</code> element.
     *
     * @param uri the Uniform Resource Identifier that qualifies an
     *   <code>EncryptedType</code>.
     */
    void setURI(String uri);

    /**
     * Returns an <code>Iterator</code> over all the child elements contained in
     * this <code>Reference</code> that will aid the recipient in retrieving the
     * <code>EncryptedKey</code> and/or <code>EncryptedData</code> elements.
     * These could include information such as XPath transforms, decompression
     * transforms, or information on how to retrieve the elements from a
     * document storage facility.
     *
     * @return child elements.
     */
    Iterator getElementRetrievalInformation();

    /**
     * Adds retrieval information.
     *
     * @param node.
     */
    void addElementRetrievalInformation(Element info);

    /**
     * Removes the specified retrieval information.
     *
     * @param node.
     */
    void removeElementRetrievalInformation(Element info);
}
--- XMLCipher.java.orig 2004-02-19 18:57:48.000000000 +0530
+++ XMLCipher.java      2004-02-19 21:38:33.000000000 +0530
@@ -1728,7 +1728,7 @@
         * Create a new ReferenceList object
         */
        public ReferenceList createReferenceList(int type) {
-               return (new ReferenceList(type));
+               return (_factory.newReferenceList(type));
        }
        
        /**
@@ -2080,7 +2080,7 @@
          *
          */
         ReferenceList newReferenceList(int type) {
-            return (new ReferenceList(type));
+            return (new ReferenceListImpl(type));
         }
 
         /**
@@ -2131,24 +2131,34 @@
             // Figure out how to make this pesky line work..
             // <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
 
-            // TODO: ///////////////////////////////////////////////////////////
-            // Implement properly, implement a KeyInfo marshaler.
+            // TODO: Work out how to handle relative URI
+
             Element originatorKeyInfoElement =
                 (Element) element.getElementsByTagNameNS(
                     EncryptionConstants.EncryptionSpecNS,
                     EncryptionConstants._TAG_ORIGINATORKEYINFO).item(0);
             if (null != originatorKeyInfoElement) {
-                result.setOriginatorKeyInfo(null);
+                try {
+                    result.setOriginatorKeyInfo(
+                        new KeyInfo(originatorKeyInfoElement, null));
+                } catch (XMLSecurityException xse) {
+                    throw new XMLEncryptionException("empty", xse);
+                }
             }
 
-            // TODO: ///////////////////////////////////////////////////////////
-            // Implement properly, implement a KeyInfo marshaler.
+            // TODO: Work out how to handle relative URI
+
             Element recipientKeyInfoElement =
                 (Element) element.getElementsByTagNameNS(
                     EncryptionConstants.EncryptionSpecNS,
                     EncryptionConstants._TAG_RECIPIENTKEYINFO).item(0);
             if (null != recipientKeyInfoElement) {
-                result.setRecipientKeyInfo(null);
+                try {
+                    result.setRecipientKeyInfo(
+                        new KeyInfo(recipientKeyInfoElement, null));
+                } catch (XMLSecurityException xse) {
+                    throw new XMLEncryptionException("empty", xse);
+                }
             }
 
             return (result);
@@ -2585,7 +2595,7 @@
                 // complain
             }
 
-            ReferenceList result = newReferenceList(type);
+            ReferenceList result = new ReferenceListImpl(type);
             NodeList list = null;
             switch (type) {
                 case ReferenceList.DATA_REFERENCE:
@@ -2599,7 +2609,7 @@
                             ((Element) list.item(0)).getNodeValue()).toString();
                     } catch (URI.MalformedURIException mfue) {
                     }
-                    result.add(ReferenceList.newDataReference(uri));
+                    result.add(result.newDataReference(uri));
                 }
                 case ReferenceList.KEY_REFERENCE:
                 list = element.getElementsByTagNameNS(
@@ -2612,7 +2622,7 @@
                             ((Element) list.item(0)).getNodeValue()).toString();
                     } catch (URI.MalformedURIException mfue) {
                     }
-                    result.add(ReferenceList.newKeyReference(uri));
+                    result.add(result.newKeyReference(uri));
                 }
             }
 
@@ -2690,9 +2700,7 @@
         }
 
         Element toElement(ReferenceList referenceList) {
-            // NOTE: ///////////////////////////////////////////////////////////
-            // TODO: Complete
-            return (null);
+            return ((ReferenceListImpl) referenceList).toElement();
         }
 
         /**
@@ -2814,10 +2822,10 @@
                     }
                 }
                 if (null != originatorKeyInfo) {
-                    // TODO: complete
+                    result.appendChild(originatorKeyInfo.getElement());
                 }
                 if (null != recipientKeyInfo) {
-                    // TODO: complete
+                    result.appendChild(recipientKeyInfo.getElement());
                 }
 
                 return (result);
@@ -3205,7 +3213,7 @@
                         super.getEncryptionMethod()).toElement());
                 }
                 if (null != super.getKeyInfo()) {
-                    // TODO: complete
+                    result.appendChild(super.getKeyInfo().getElement());
                 }
                 result.appendChild(
                     ((CipherDataImpl) super.getCipherData()).toElement());
@@ -3214,7 +3222,8 @@
                         super.getEncryptionProperties()).toElement());
                 }
                 if (referenceList != null && !referenceList.isEmpty()) {
-                    // TODO: complete
+                    result.appendChild(((ReferenceListImpl)
+                        getReferenceList()).toElement());
                 }
                 if (null != carriedName) {
                     result.appendChild(
@@ -3612,5 +3621,151 @@
                        }
 
         }
+
+        //<element name='ReferenceList'>
+        //    <complexType>
+        //        <choice minOccurs='1' maxOccurs='unbounded'>
+        //            <element name='DataReference' type='xenc:ReferenceType'/>
+        //            <element name='KeyReference' type='xenc:ReferenceType'/>
+        //        </choice>
+        //    </complexType>
+        //</element>
+        private class ReferenceListImpl implements ReferenceList {
+            private Class sentry;
+            private List references;
+
+            public ReferenceListImpl(int type) {
+                if (type == ReferenceList.DATA_REFERENCE) {
+                    sentry = DataReference.class;
+                } else if (type == ReferenceList.KEY_REFERENCE) {
+                    sentry = KeyReference.class;
+                } else {
+                    throw new IllegalArgumentException();
+                }
+                references = new LinkedList();
+            }
+
+            public void add(Reference reference) {
+                if (!reference.getClass().equals(sentry)) {
+                    throw new IllegalArgumentException();
+                } else {
+                    references.add(reference);
+                }
+            }
+
+            public void remove(Reference reference) {
+                if (!reference.getClass().equals(sentry)) {
+                    throw new IllegalArgumentException();
+                } else {
+                    references.remove(reference);
+                }
+            }
+
+            public int size() {
+                return (references.size());
+            }
+
+            public boolean isEmpty() {
+                return (references.isEmpty());
+            }
+
+            public Iterator getReferences() {
+                return (references.iterator());
+            }
+
+            Element toElement() {
+                Element result = ElementProxy.createElementForFamily(
+                    _contextDocument,
+                    EncryptionConstants.EncryptionSpecNS,
+                    EncryptionConstants._TAG_REFERENCELIST);
+                Iterator eachReference = references.iterator();
+                while (eachReference.hasNext()) {
+                    Reference reference = (Reference) eachReference.next();
+                    result.appendChild(
+                        ((ReferenceImpl) reference).toElement());
+                }
+                return (result);
+            }
+
+            public Reference newDataReference(String uri) {
+                return (new DataReference(uri));
+            }
+
+            public Reference newKeyReference(String uri) {
+                return (new KeyReference(uri));
+            }
+
+            /**
+             * <code>ReferenceImpl</code> is an implementation of
+             * <code>Reference</code>.
+             *
+             * @see Reference.
+             */
+            private abstract class ReferenceImpl implements Reference {
+                private String uri;
+                private List referenceInformation;
+
+                ReferenceImpl(String _uri) {
+                    this.uri = _uri;
+                    referenceInformation = new LinkedList();
+                }
+            
+                public String getURI() {
+                    return (uri);
+                }
+
+                public Iterator getElementRetrievalInformation() {
+                    return (referenceInformation.iterator());
+                }
+
+                public void setURI(String _uri) {
+                       this.uri = _uri;
+                }
+
+                public void removeElementRetrievalInformation(Element node) {
+                    referenceInformation.remove(node);
+                }
+
+                public void addElementRetrievalInformation(Element node) {
+                    referenceInformation.add(node);
+                }
+
+                public abstract Element toElement();
+
+                Element toElement(String tagName) {
+                    Element result = ElementProxy.createElementForFamily(
+                        _contextDocument,
+                        EncryptionConstants.EncryptionSpecNS,
+                        tagName);
+                    result.setAttribute(EncryptionConstants._ATT_URI, uri);
+
+                    // TODO: Need to martial referenceInformation
+                    // Figure out how to make this work..
+                    // <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
+
+                    return (result);
+                }
+            }
+
+            private class DataReference extends ReferenceImpl {
+                DataReference(String uri) {
+                    super(uri);
+                }
+
+                public Element toElement() {
+                    return toElement(EncryptionConstants._TAG_DATAREFERENCE);
+                }
+            }
+
+            private class KeyReference extends ReferenceImpl {
+                KeyReference(String uri) {
+                    super (uri);
+                }
+
+                public Element toElement() {
+                    return toElement(EncryptionConstants._TAG_KEYREFERENCE);
+                }
+            }
+        }
     }
 }

Reply via email to