| /* |
| * The Apache Software License, Version 1.1 |
| * |
| * |
| * Copyright (c) 1999 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 "<WebSig>" 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 and was |
| * originally based on software copyright (c) 2001, Institute for |
| * Data Communications Systems, <http://www.nue.et-inf.uni-siegen.de/>. |
| * The development of this software was partly funded by the European |
| * Commission in the <WebSig> project in the ISIS Programme. |
| * For more information on the Apache Software Foundation, please see |
| * <http://www.apache.org/>. |
| */ |
| package org.apache.xml.security.encryption; |
| |
| |
| import java.io.IOException; |
| import java.io.StringReader; |
| import java.io.StringWriter; |
| import java.lang.Integer; |
| import java.security.InvalidKeyException; |
| import java.security.Key; |
| import java.security.InvalidAlgorithmParameterException; |
| import java.security.NoSuchAlgorithmException; |
| import java.security.NoSuchProviderException; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Map; |
| import javax.crypto.BadPaddingException; |
| import javax.crypto.Cipher; |
| import javax.crypto.IllegalBlockSizeException; |
| import javax.crypto.NoSuchPaddingException; |
| import javax.crypto.spec.IvParameterSpec; |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.ParserConfigurationException; |
| import org.apache.xml.security.keys.KeyInfo; |
| import org.apache.xml.security.utils.Constants; |
| import org.apache.xml.security.utils.EncryptionConstants; |
| import org.apache.xml.security.algorithms.MessageDigestAlgorithm; |
| import org.apache.xml.security.algorithms.JCEMapper; |
| import org.apache.xml.security.c14n.Canonicalizer; |
| import org.apache.xml.security.transforms.Transform; |
| import org.apache.xml.security.utils.ElementProxy; |
| import org.apache.xml.security.exceptions.Base64DecodingException; |
| import org.apache.xml.security.exceptions.XMLSecurityException; |
| import org.apache.xml.serialize.OutputFormat; |
| import org.apache.xml.serialize.XMLSerializer; |
| import org.apache.xml.utils.URI; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.DocumentFragment; |
| import org.w3c.dom.NamedNodeMap; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| import org.xml.sax.InputSource; |
| import org.xml.sax.SAXException; |
| import sun.misc.BASE64Encoder; |
| import org.apache.xml.security.utils.Base64; |
| |
| |
| /** |
| * <code>XMLCipher</code> encrypts and decrypts the contents of |
| * <code>Document</code>s, <code>Element</code>s and <code>Element</code> |
| * contents. It was designed to resemble <code>javax.crypto.Cipher</code> in |
| * order to facilitate understanding of its functioning. |
| * |
| * @author Axl Mattheus (Sun Microsystems) |
| * @author Christian Geuer-Pollmann |
| */ |
| public class XMLCipher { |
| |
| private static org.apache.commons.logging.Log logger = |
| org.apache.commons.logging.LogFactory.getLog(XMLCipher.class.getName()); |
| |
| public static final String TRIPLEDES = |
| EncryptionConstants.ALGO_ID_BLOCKCIPHER_TRIPLEDES; |
| public static final String AES_128 = |
| EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128; |
| public static final String AES_256 = |
| EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256; |
| public static final String AES_192 = |
| EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192; |
| public static final String RSA_v1dot5 = |
| EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15; |
| public static final String RSA_OAEP = |
| EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP; |
| public static final String DIFFIE_HELLMAN = |
| EncryptionConstants.ALGO_ID_KEYAGREEMENT_DH; |
| public static final String TRIPLEDES_KeyWrap = |
| EncryptionConstants.ALGO_ID_KEYWRAP_TRIPLEDES; |
| public static final String AES_128_KeyWrap = |
| EncryptionConstants.ALGO_ID_KEYWRAP_AES128; |
| public static final String AES_256_KeyWrap = |
| EncryptionConstants.ALGO_ID_KEYWRAP_AES256; |
| public static final String AES_192_KeyWrap = |
| EncryptionConstants.ALGO_ID_KEYWRAP_AES192; |
| public static final String SHA1 = |
| Constants.ALGO_ID_DIGEST_SHA1; |
| public static final String SHA256 = |
| MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA256; |
| public static final String SHA512 = |
| MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA512; |
| public static final String RIPEMD_160 = |
| MessageDigestAlgorithm.ALGO_ID_DIGEST_RIPEMD160; |
| public static final String XML_DSIG = |
| Constants.SignatureSpecNS; |
| public static final String N14C_XML = |
| Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS; |
| public static final String N14C_XML_WITH_COMMENTS = |
| Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS; |
| public static final String EXCL_XML_N14C = |
| Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS; |
| public static final String EXCL_XML_N14C_WITH_COMMENTS = |
| Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS; |
| public static final String BASE64_ENCODING = |
| org.apache.xml.security.transforms.Transforms.TRANSFORM_BASE64_DECODE; |
| |
| public static final int ENCRYPT_MODE = Cipher.ENCRYPT_MODE; |
| public static final int DECRYPT_MODE = Cipher.DECRYPT_MODE; |
| public static final int UNWRAP_MODE = Cipher.UNWRAP_MODE; |
| public static final int WRAP_MODE = Cipher.WRAP_MODE; |
| |
| private static XMLCipher instance = null; |
| private static final String ENC_ALGORITHMS = TRIPLEDES + "\n" + |
| AES_128 + "\n" + AES_256 + "\n" + AES_192 + "\n" + RSA_v1dot5 + "\n" + |
| RSA_OAEP + "\n" + TRIPLEDES_KeyWrap + "\n" + AES_128_KeyWrap + "\n" + |
| AES_256_KeyWrap + "\n" + AES_192_KeyWrap+ "\n"; |
| private static final String ALGORITHMS = TRIPLEDES + "\n" + |
| AES_128 + "\n" + AES_256 + "\n" + AES_192 + "\n" + RSA_v1dot5 + "\n" + |
| RSA_OAEP + "\n" + DIFFIE_HELLMAN + "\n" + TRIPLEDES_KeyWrap + "\n" + |
| AES_128_KeyWrap + "\n" + AES_256_KeyWrap + "\n" + |
| AES_192_KeyWrap+ "\n" + SHA1 + "\n" + SHA256 + "\n" + SHA512 + "\n" + |
| RIPEMD_160 + "\n" + XML_DSIG + "\n" + N14C_XML + "\n" + |
| N14C_XML_WITH_COMMENTS + "\n" + EXCL_XML_N14C + "\n" + |
| EXCL_XML_N14C_WITH_COMMENTS; |
| |
| private Cipher contextCipher; |
| private int cipherMode = Integer.MIN_VALUE; |
| private String algorithm = null; // URI for requested algorithm |
| private String requestedJCEProvider = null; |
| private Document contextDocument; |
| private Factory factory; |
| private Serializer serializer; |
| private Map enc2JCE; |
| private Map enc2IV; |
| private Key localKey; |
| |
| /** |
| * Creates a new <code>XMLCipher</code>. |
| * |
| * @since 1.0. |
| */ |
| private XMLCipher() { |
| logger.debug("Constructing XMLCipher..."); |
| |
| factory = new Factory(); |
| serializer = new Serializer(); |
| // block encryption |
| enc2JCE = new HashMap(); |
| enc2JCE.put(TRIPLEDES, "DESede/CBC/NoPadding"); |
| enc2JCE.put(AES_128, "AES/CBC/PKCS5Padding"); |
| enc2JCE.put(AES_256, "AES/CBC/PKCS5Padding"); |
| enc2JCE.put(AES_192, "AES/CBC/PKCS5Padding"); |
| |
| // key encryption |
| enc2JCE.put(RSA_v1dot5, "RSA/ECB/PKCS1Padding"); |
| enc2JCE.put(RSA_OAEP, "RSA/ECB/OAEPPadding"); |
| enc2JCE.put(TRIPLEDES_KeyWrap, "DESede"); |
| enc2JCE.put(AES_128_KeyWrap, "AES"); |
| enc2JCE.put(AES_256_KeyWrap, "AES"); |
| enc2JCE.put(AES_192_KeyWrap, "AES"); |
| } |
| |
| /** |
| * Checks to ensure that the supplied algorithm is valid. |
| * |
| * @param algorithm the algorithm to check. |
| * @returm true if the algorithm is valid, otherwise false. |
| * @since 1.0. |
| */ |
| private static boolean isValidEncryptionAlgorithm(String algorithm) { |
| boolean result = ( |
| algorithm.equals(TRIPLEDES) || |
| algorithm.equals(AES_128) || |
| algorithm.equals(AES_256) || |
| algorithm.equals(AES_192) || |
| algorithm.equals(RSA_v1dot5) || |
| algorithm.equals(RSA_OAEP) || |
| algorithm.equals(TRIPLEDES_KeyWrap) || |
| algorithm.equals(AES_128_KeyWrap) || |
| algorithm.equals(AES_256_KeyWrap) || |
| algorithm.equals(AES_192_KeyWrap) |
| ); |
| |
| return (result); |
| } |
| |
| /** |
| * Returns an <code>XMLCipher</code> that implements the specified |
| * transformation and operates on the specified context document. |
| * <p> |
| * If the default provider package supplies an implementation of the |
| * requested transformation, an instance of Cipher containing that |
| * implementation is returned. If the transformation is not available in |
| * the default provider package, other provider packages are searched. |
| * <p> |
| * <b>NOTE<sub>1</sub>:</b> The transformation name does not follow the same |
| * pattern as that oulined in the Java Cryptography Extension Reference |
| * Guide but rather that specified by the XML Encryption Syntax and |
| * Processing document. The rational behind this is to make it easier for a |
| * novice at writing Java Encryption software to use the library. |
| * <p> |
| * <b>NOTE<sub>2</sub>:</b> <code>getInstance()</code> does not follow the |
| * same pattern regarding exceptional conditions as that used in |
| * <code>javax.crypto.Cipher</code>. Instead, it only throws an |
| * <code>XMLEncryptionException</code> which wraps an underlying exception. |
| * The stack trace from the exception should be self explanitory. |
| * |
| * @param transformation the name of the transformation, e.g., |
| * <code>XMLCipher.TRIPLEDES</code> which is shorthand for |
| * "http://www.w3.org/2001/04/xmlenc#tripledes-cbc" |
| * @throws <code>XMLEncryptionException</code>. |
| * @see javax.crypto.Cipher#getInstance |
| */ |
| public static XMLCipher getInstance(String transformation) throws |
| XMLEncryptionException { |
| // sanity checks |
| logger.debug("Getting XMLCipher..."); |
| if (null == transformation) |
| logger.error("Transformation unexpectedly null..."); |
| if(!isValidEncryptionAlgorithm(transformation)) |
| logger.error("Alogorithm unvalid, expected one of " + ENC_ALGORITHMS); |
| |
| if (null == instance) { |
| instance = new XMLCipher(); |
| } |
| |
| instance.algorithm = transformation; |
| |
| try { |
| String jceAlgorithm = (String) instance.enc2JCE.get(transformation); |
| instance.contextCipher = Cipher.getInstance(jceAlgorithm); |
| |
| logger.debug("cihper.algoritm = " + |
| instance.contextCipher.getAlgorithm()); |
| } catch (NoSuchAlgorithmException nsae) { |
| throw new XMLEncryptionException("empty", nsae); |
| } catch (NoSuchPaddingException nspe) { |
| throw new XMLEncryptionException("empty", nspe); |
| } |
| |
| return (instance); |
| } |
| |
| /** |
| * Returns an <code>XMLCipher</code> that implements the specified |
| * transformation and operates on the specified context document. |
| * |
| * @param transformation the name of the transformation, e.g., |
| * <code>XMLCipher.TRIPLEDES</code> which is shorthand for |
| * "http://www.w3.org/2001/04/xmlenc#tripledes-cbc" |
| * @param provider the JCE provider that supplies the transformation |
| * @throws <code>XMLEncryptionException</code>. |
| */ |
| public static XMLCipher getInstance(String transformation, String provider) |
| throws XMLEncryptionException { |
| // sanity checks |
| logger.debug("Getting XMLCipher..."); |
| if (null == transformation) |
| logger.error("Transformation unexpectedly null..."); |
| if(null == provider) |
| logger.error("Provider unexpectedly null.."); |
| if("" == provider) |
| logger.error("Provider's value unexpectedly not specified..."); |
| if(!isValidEncryptionAlgorithm(transformation)) |
| logger.error("Alogorithm unvalid, expected one of " + ENC_ALGORITHMS); |
| |
| if (null == instance) { |
| instance = new XMLCipher(); |
| } |
| |
| instance.algorithm = transformation; |
| instance.requestedJCEProvider = provider; |
| |
| try { |
| String jceAlgorithm = (String) instance.enc2JCE.get(transformation); |
| instance.contextCipher = Cipher.getInstance(jceAlgorithm, provider); |
| |
| logger.debug("cipher.algorithm = " + |
| instance.contextCipher.getAlgorithm()); |
| logger.debug("provider.name = " + provider); |
| } catch (NoSuchAlgorithmException nsae) { |
| throw new XMLEncryptionException("empty", nsae); |
| } catch (NoSuchProviderException nspre) { |
| throw new XMLEncryptionException("empty", nspre); |
| } catch (NoSuchPaddingException nspe) { |
| throw new XMLEncryptionException("empty", nspe); |
| } |
| |
| return (instance); |
| } |
| |
| /** |
| * Initializes this cipher with a key. |
| * <p> |
| * The cipher is initialized for one of the following four operations: |
| * encryption, decryption, key wrapping or key unwrapping, depending on the |
| * value of opmode. |
| * |
| * @param opmode the operation mode of this cipher (this is one of the |
| * following: ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE or UNWRAP_MODE) |
| * @param key |
| * @see javax.crypto.Cipher#init |
| */ |
| public void init(int opmode, Key key) throws XMLEncryptionException { |
| // sanity checks |
| logger.debug("Initializing XMLCipher..."); |
| if (opmode != ENCRYPT_MODE && opmode != DECRYPT_MODE) |
| logger.error("Mode unexpectedly invalid..."); |
| logger.debug("opmode = " + |
| ((opmode == ENCRYPT_MODE) ? "ENCRYPT_MODE" : "DECRYPT_MODE")); |
| |
| cipherMode = opmode; |
| localKey = key; |
| |
| } |
| |
| /** |
| * Encrypts an <code>Element</code> and replaces it with its encrypted |
| * counterpart in the context <code>Document</code>, that is, the |
| * <code>Document</code> specified when one calls |
| * {@link #getInstance(Document, String) getInstance}. |
| * |
| * @param element the <code>Element</code> to encrypt. |
| * @return the context <code>Document</code> with the encrypted |
| * <code>Element</code> having replaced the source <code>Element</code>. |
| */ |
| private Document encryptElement(Element element) throws |
| XMLEncryptionException { |
| logger.debug("Encrypting element..."); |
| if(null == element) |
| logger.error("Element unexpectedly null..."); |
| if(cipherMode != ENCRYPT_MODE) |
| logger.error("XMLCipher unexpectedly not in ENCRYPT_MODE..."); |
| |
| String serializedOctets = serializer.serialize(element); |
| logger.debug("Serialized octets:\n" + serializedOctets); |
| |
| byte[] encryptedBytes = null; |
| // Now create the working cipher |
| |
| String jceAlgorithm = |
| JCEMapper.translateURItoJCEID(algorithm).getAlgorithmID(); |
| String provider; |
| |
| if (requestedJCEProvider == null) |
| provider = |
| JCEMapper.translateURItoJCEID(algorithm).getProviderId(); |
| else |
| provider = requestedJCEProvider; |
| |
| logger.debug("provider = " + provider + "alg = " + jceAlgorithm); |
| |
| Cipher c; |
| try { |
| c = Cipher.getInstance(jceAlgorithm, provider); |
| } catch (NoSuchAlgorithmException nsae) { |
| throw new XMLEncryptionException("empty", nsae); |
| } catch (NoSuchProviderException nspre) { |
| throw new XMLEncryptionException("empty", nspre); |
| } catch (NoSuchPaddingException nspae) { |
| throw new XMLEncryptionException("empty", nspae); |
| } |
| |
| // Now perform the encryption |
| |
| try { |
| // Should internally generate an IV |
| // todo - allow user to set an IV |
| c.init(cipherMode, localKey); |
| } catch (InvalidKeyException ike) { |
| throw new XMLEncryptionException("empty", ike); |
| } |
| |
| try { |
| encryptedBytes = |
| c.doFinal(serializedOctets.getBytes()); |
| |
| logger.debug("Expected cipher.outputSize = " + |
| Integer.toString(c.getOutputSize( |
| serializedOctets.getBytes().length))); |
| logger.debug("Actual cipher.outputSize = " + |
| Integer.toString(encryptedBytes.length)); |
| } catch (IllegalStateException ise) { |
| throw new XMLEncryptionException("empty", ise); |
| } catch (IllegalBlockSizeException ibse) { |
| throw new XMLEncryptionException("empty", ibse); |
| } catch (BadPaddingException bpe) { |
| throw new XMLEncryptionException("empty", bpe); |
| } |
| |
| // Now build up to a properly XML Encryption encoded octet stream |
| // IvParameterSpec iv; |
| |
| byte[] iv = c.getIV(); |
| byte[] finalEncryptedBytes = |
| new byte[iv.length + encryptedBytes.length]; |
| System.arraycopy(iv, 0, finalEncryptedBytes, 0, |
| iv.length); |
| System.arraycopy(encryptedBytes, 0, finalEncryptedBytes, |
| iv.length, |
| encryptedBytes.length); |
| |
| String base64EncodedEncryptedOctets = new BASE64Encoder().encode( |
| finalEncryptedBytes); |
| |
| logger.debug("Encrypted octets:\n" + base64EncodedEncryptedOctets); |
| logger.debug("Encrypted octets length = " + |
| base64EncodedEncryptedOctets.length()); |
| |
| EncryptedData data = createEncryptedData(CipherData.VALUE_TYPE, |
| base64EncodedEncryptedOctets); |
| try { |
| data.setType(new URI(EncryptionConstants.TYPE_ELEMENT).toString()); |
| EncryptionMethod method = factory.newEncryptionMethod( |
| new URI(algorithm).toString()); |
| data.setEncryptionMethod(method); |
| } catch (URI.MalformedURIException mfue) { |
| throw new XMLEncryptionException("empty", mfue); |
| } |
| |
| Element encryptedElement = factory.toElement(data); |
| |
| Node sourceParent = element.getParentNode(); |
| sourceParent.replaceChild(encryptedElement, element); |
| |
| return (contextDocument); |
| } |
| |
| /** |
| * Encrypts a <code>NodeList</code> (the contents of an |
| * <code>Element</code>) and replaces its parent <code>Element</code>'s |
| * content with this the resulting <code>EncryptedType</code> within the |
| * context <code>Document</code>, that is, the <code>Document</code> |
| * specified when one calls |
| * {@link #getInstance(Document, String) getInstance}. |
| * |
| * @param content the <code>NodeList</code> to encrypt. |
| * @return the context <code>Document</code> with the encrypted |
| * <code>NodeList</code> having replaced the content of the source |
| * <code>Element</code>. |
| */ |
| private Document encryptElementContent(Element element) throws |
| XMLEncryptionException { |
| logger.debug("Encrypting element content..."); |
| if(null == element) |
| logger.error("Element unexpectedly null..."); |
| if(cipherMode != ENCRYPT_MODE) |
| logger.error("XMLCipher unexpectedly not in ENCRYPT_MODE..."); |
| |
| NodeList children = element.getChildNodes(); |
| String serializedOctets = null; |
| if ((null != children)) { |
| serializedOctets = serializer.serialize(children); |
| } else { |
| Object exArgs[] = {"Element has no content."}; |
| throw new XMLEncryptionException("empty", exArgs); |
| } |
| logger.debug("Serialized octets:\n" + serializedOctets); |
| |
| byte[] encryptedBytes = null; |
| try { |
| encryptedBytes = |
| contextCipher.doFinal(serializedOctets.getBytes()); |
| |
| logger.debug("Expected cipher.outputSize = " + |
| Integer.toString(contextCipher.getOutputSize( |
| serializedOctets.getBytes().length))); |
| logger.debug("Actual cipher.outputSize = " + |
| Integer.toString(encryptedBytes.length)); |
| } catch (IllegalStateException ise) { |
| throw new XMLEncryptionException("empty", ise); |
| } catch (IllegalBlockSizeException ibse) { |
| throw new XMLEncryptionException("empty", ibse); |
| } catch (BadPaddingException bpe) { |
| throw new XMLEncryptionException("empty", bpe); |
| } |
| |
| String base64EncodedEncryptedOctets = new BASE64Encoder().encode( |
| encryptedBytes); |
| |
| logger.debug("Encrypted octets:\n" + base64EncodedEncryptedOctets); |
| logger.debug("Encrypted octets length = " + |
| base64EncodedEncryptedOctets.length()); |
| |
| EncryptedData data = createEncryptedData(CipherData.VALUE_TYPE, |
| base64EncodedEncryptedOctets); |
| try { |
| data.setType(new URI(EncryptionConstants.TYPE_CONTENT).toString()); |
| EncryptionMethod method = factory.newEncryptionMethod( |
| new URI(algorithm).toString()); |
| data.setEncryptionMethod(method); |
| } catch (URI.MalformedURIException mfue) { |
| throw new XMLEncryptionException("empty", mfue); |
| } |
| |
| Element encryptedElement = factory.toElement(data); |
| removeContent(element); |
| element.appendChild(encryptedElement); |
| |
| return (contextDocument); |
| } |
| |
| /** |
| * Process a DOM <code>Document</code> node. The processing depends on the |
| * initialization parameters of {@link #init(int, Key) init()}. |
| * |
| * @param context the context <code>Document</code>. |
| * @param source the <code>Document</code> to be encrypted or decrypted. |
| * @return the processed <code>Document</code>. |
| * @throws XMLEnccryptionException to indicate any exceptional conditions. |
| */ |
| public Document doFinal(Document context, Document source) throws |
| XMLEncryptionException { |
| logger.debug("Processing source document..."); |
| if(null == context) |
| logger.error("Context document unexpectedly null..."); |
| if(null == source) |
| logger.error("Source document unexpectedly null..."); |
| |
| instance.contextDocument = context; |
| |
| Document result = null; |
| |
| switch (cipherMode) { |
| case DECRYPT_MODE: |
| result = decryptElement(source.getDocumentElement()); |
| break; |
| case ENCRYPT_MODE: |
| result = encryptElement(source.getDocumentElement()); |
| break; |
| case UNWRAP_MODE: |
| break; |
| case WRAP_MODE: |
| break; |
| default: |
| throw new XMLEncryptionException( |
| "empty", new IllegalStateException()); |
| } |
| |
| return (result); |
| } |
| |
| /** |
| * Process a DOM <code>Element</code> node. The processing depends on the |
| * initialization parameters of {@link #init(int, Key) init()}. |
| * |
| * @param context the context <code>Document</code>. |
| * @param element the <code>Element</code> to be encrypted. |
| * @return the processed <code>Document</code>. |
| * @throws XMLEnccryptionException to indicate any exceptional conditions. |
| */ |
| public Document doFinal(Document context, Element element) throws |
| XMLEncryptionException { |
| logger.debug("Processing source element..."); |
| if(null == context) |
| logger.error("Context document unexpectedly null..."); |
| if(null == element) |
| logger.error("Source element unexpectedly null..."); |
| |
| instance.contextDocument = context; |
| |
| Document result = null; |
| |
| switch (cipherMode) { |
| case DECRYPT_MODE: |
| result = decryptElement(element); |
| break; |
| case ENCRYPT_MODE: |
| result = encryptElement(element); |
| break; |
| case UNWRAP_MODE: |
| break; |
| case WRAP_MODE: |
| break; |
| default: |
| throw new XMLEncryptionException( |
| "empty", new IllegalStateException()); |
| } |
| |
| return (result); |
| } |
| |
| /** |
| * Process the contents of a DOM <code>Element</code> node. The processing |
| * depends on the initialization parameters of |
| * {@link #init(int, Key) init()}. |
| * |
| * @param context the context <code>Document</code>. |
| * @param element the <code>Element</code> which contents is to be |
| * encrypted. |
| * @return the processed <code>Document</code>. |
| * @throws XMLEnccryptionException to indicate any exceptional conditions. |
| */ |
| public Document doFinal(Document context, Element element, boolean content) |
| throws XMLEncryptionException { |
| logger.debug("Processing source element..."); |
| if(null == context) |
| logger.error("Context document unexpectedly null..."); |
| if(null == element) |
| logger.error("Source element unexpectedly null..."); |
| |
| instance.contextDocument = context; |
| |
| Document result = null; |
| |
| switch (cipherMode) { |
| case DECRYPT_MODE: |
| if (content) { |
| result = decryptElementContent(element); |
| } else { |
| result = decryptElement(element); |
| } |
| break; |
| case ENCRYPT_MODE: |
| if (content) { |
| result = encryptElementContent(element); |
| } else { |
| result = encryptElement(element); |
| } |
| break; |
| case UNWRAP_MODE: |
| break; |
| case WRAP_MODE: |
| break; |
| default: |
| throw new XMLEncryptionException( |
| "empty", new IllegalStateException()); |
| } |
| |
| return (null); |
| } |
| |
| /** |
| * Process a DOM <code>NodeList</code>. The processing depends on the |
| * initialization parameters of {@link #init(int, Key) init()}. |
| * |
| * @param context the context <code>Document</code>. |
| * @param elements the <code>NodeList</code> which contents is to be |
| * processed. |
| * @return the processed <code>Document</code>. |
| * @throws XMLEnccryptionException to indicate any exceptional conditions. |
| */ |
| private Document doFinal(Document context, NodeList elements) throws |
| XMLEncryptionException { |
| return (null); |
| } |
| |
| /** |
| * Process an XPath expression. The processing depends on the |
| * initialization parameters of {@link #init(int, Key) init()}. |
| * |
| * @param xpathExpression the expression to process. |
| * @return the processed <code>Document</code>. |
| * @throws XMLEncryptionException to indicat any exceptional conditions. |
| */ |
| private Document doFinal(String xpathExpression) throws |
| XMLEncryptionException { |
| return (null); |
| } |
| |
| /** |
| * |
| */ |
| private Document doFinal(Document context, Element element, |
| EncryptedData data) throws XMLEncryptionException { |
| return (null); |
| } |
| |
| /** |
| * |
| */ |
| private Document doFinal(Document context, Element element, |
| EncryptedKey key) throws XMLEncryptionException { |
| return (null); |
| } |
| |
| /** |
| * Returns an <code>EncryptedData</code> interface. Use this operation if |
| * you want to have full control over the contents of the |
| * <code>EncryptedData</code> structure. |
| * |
| * @param context the context <code>Document</code>. |
| * @param element the <code>Element</code> that will be encrypted. |
| * @throws XMLEncryptionException. |
| */ |
| public EncryptedData encryptData(Document context, Element element) throws |
| XMLEncryptionException { |
| logger.debug("Encrypting element..."); |
| if(null == context) |
| logger.error("Context document unexpectedly null..."); |
| if(null == element) |
| logger.error("Element unexpectedly null..."); |
| if(cipherMode != ENCRYPT_MODE) |
| logger.error("XMLCipher unexpectedly not in ENCRYPT_MODE..."); |
| |
| instance.contextDocument = context; |
| |
| String serializedOctets = serializer.serialize(element); |
| logger.debug("Serialized octets:\n" + serializedOctets); |
| |
| byte[] encryptedBytes = null; |
| try { |
| encryptedBytes = |
| contextCipher.doFinal(serializedOctets.getBytes()); |
| |
| logger.debug("Expected cipher.outputSize = " + |
| Integer.toString(contextCipher.getOutputSize( |
| serializedOctets.getBytes().length))); |
| logger.debug("Actual cipher.outputSize = " + |
| Integer.toString(encryptedBytes.length)); |
| } catch (IllegalStateException ise) { |
| throw new XMLEncryptionException("empty", ise); |
| } catch (IllegalBlockSizeException ibse) { |
| throw new XMLEncryptionException("empty", ibse); |
| } catch (BadPaddingException bpe) { |
| throw new XMLEncryptionException("empty", bpe); |
| } |
| |
| String base64EncodedEncryptedOctets = new BASE64Encoder().encode( |
| encryptedBytes); |
| |
| logger.debug("Encrypted octets:\n" + base64EncodedEncryptedOctets); |
| logger.debug("Encrypted octets length = " + |
| base64EncodedEncryptedOctets.length()); |
| |
| EncryptedData data = createEncryptedData(CipherData.VALUE_TYPE, |
| base64EncodedEncryptedOctets); |
| try { |
| data.setType(new URI(EncryptionConstants.TYPE_ELEMENT).toString()); |
| EncryptionMethod method = factory.newEncryptionMethod( |
| new URI(algorithm).toString()); |
| data.setEncryptionMethod(method); |
| } catch (URI.MalformedURIException mfue) { |
| throw new XMLEncryptionException("empty", mfue); |
| } |
| |
| return (data); |
| } |
| |
| /** |
| * Returns an <code>EncryptedData</code> interface. Use this operation if |
| * you want to load an <code>EncryptedData</code> structure from a DOM |
| * structure and manipulate the contents |
| * |
| * @param context the context <code>Document</code>. |
| * @param element the <code>Element</code> that will be loaded |
| * @throws XMLEncryptionException. |
| */ |
| public EncryptedData loadEncryptedData(Document context, Element element) |
| throws XMLEncryptionException { |
| logger.debug("Loading encrypted element..."); |
| if(null == context) |
| logger.error("Context document unexpectedly null..."); |
| if(null == element) |
| logger.error("Element unexpectedly null..."); |
| if(cipherMode != DECRYPT_MODE) |
| logger.error("XMLCipher unexpectedly not in DECRYPT_MODE..."); |
| |
| instance.contextDocument = context; |
| EncryptedData encryptedData = factory.newEncryptedData(element); |
| |
| return (encryptedData); |
| } |
| |
| |
| |
| |
| /** |
| * Decrypts an <code>EncryptedKey</code> object. |
| */ |
| public EncryptedKey encryptKey(Document context, Element element) throws |
| XMLEncryptionException { |
| return (null); |
| } |
| |
| /** |
| * Removes the contents of a <code>Node</code>. |
| * |
| * @param node the <code>Node</code> to clear. |
| */ |
| private void removeContent(Node node) { |
| NodeList list = node.getChildNodes(); |
| if (list.getLength() > 0) { |
| Node n = list.item(0); |
| if (null != n) { |
| n.getParentNode().removeChild(n); |
| } |
| removeContent(node); |
| } |
| } |
| |
| /** |
| * Decrypts <code>EncryptedData</code> in a single-part operation. |
| * |
| * @param data the <code>EncryptedData</code> to decrypt. |
| * @return the <code>Node</code> as a result of the decrypt operation. |
| */ |
| private Document decryptElement(Element element) throws |
| XMLEncryptionException { |
| |
| logger.debug("Decrypting element..."); |
| |
| if(cipherMode != DECRYPT_MODE) |
| logger.error("XMLCipher unexpectedly not in DECRYPT_MODE..."); |
| |
| EncryptedData encryptedData = factory.newEncryptedData(element); |
| |
| CipherData cipherData = encryptedData.getCipherData(); |
| String base64EncodedEncryptedOctets = null; |
| |
| if (cipherData.getDataType() == CipherData.REFERENCE_TYPE) { |
| // retrieve the cipher text |
| } else if (cipherData.getDataType() == CipherData.VALUE_TYPE) { |
| CipherValue cipherValue = cipherData.getCipherValue(); |
| base64EncodedEncryptedOctets = new String(cipherValue.getValue()); |
| } else { |
| // complain... |
| } |
| logger.debug("Encrypted octets:\n" + base64EncodedEncryptedOctets); |
| |
| byte[] encryptedBytes = null; |
| |
| try { |
| encryptedBytes = Base64.decode(base64EncodedEncryptedOctets); |
| } catch (Base64DecodingException bde) { |
| throw new XMLEncryptionException("empty", bde); |
| } |
| |
| // Now create the working cipher |
| |
| String jceAlgorithm = |
| JCEMapper.translateURItoJCEID(encryptedData.getEncryptionMethod() |
| .getAlgorithm()).getAlgorithmID(); |
| String provider; |
| |
| if (requestedJCEProvider == null) |
| provider = |
| JCEMapper.translateURItoJCEID(encryptedData |
| .getEncryptionMethod() |
| .getAlgorithm()) |
| .getProviderId(); |
| else |
| provider = requestedJCEProvider; |
| |
| Cipher c; |
| try { |
| c = Cipher.getInstance(jceAlgorithm, provider); |
| } catch (NoSuchAlgorithmException nsae) { |
| throw new XMLEncryptionException("empty", nsae); |
| } catch (NoSuchProviderException nspre) { |
| throw new XMLEncryptionException("empty", nspre); |
| } catch (NoSuchPaddingException nspae) { |
| throw new XMLEncryptionException("empty", nspae); |
| } |
| |
| |
| // Calculate the IV length and copy out |
| |
| // For now, we only work with Block ciphers, so this will work. |
| // This should probably be put into the JCE mapper. |
| |
| int ivLen = c.getBlockSize(); |
| byte[] ivBytes = new byte[ivLen]; |
| |
| // You may be able to pass the entire piece in to IvParameterSpec |
| // and it will only take the first x bytes, but no way to be certain |
| // that this will work for every JCE provider, so lets copy the |
| // necessary bytes into a dedicated array. |
| |
| System.arraycopy(encryptedBytes, 0, ivBytes, 0, ivLen); |
| IvParameterSpec iv = new IvParameterSpec(ivBytes); |
| |
| try { |
| c.init(cipherMode, localKey, iv); |
| } catch (InvalidKeyException ike) { |
| throw new XMLEncryptionException("empty", ike); |
| } catch (InvalidAlgorithmParameterException iape) { |
| throw new XMLEncryptionException("empty", iape); |
| } |
| |
| String octets = null; |
| byte[] plainBytes; |
| |
| try { |
| octets = new String(c.doFinal(encryptedBytes, ivLen, |
| encryptedBytes.length - ivLen)); |
| } catch (IllegalBlockSizeException ibse) { |
| throw new XMLEncryptionException("empty", ibse); |
| } catch (BadPaddingException bpe) { |
| throw new XMLEncryptionException("empty", bpe); |
| } |
| |
| // Now remove any padding |
| //octets = new String(padder.dePad(plainBytes)); |
| |
| |
| logger.debug("Decrypted octets:\n" + octets); |
| |
| Element sourceParent = (Element) element.getParentNode(); |
| DocumentFragment decryptedFragment = |
| serializer.deserialize(octets, sourceParent); |
| |
| // The de-serialiser returns a fragment whose children we need to |
| // take on. |
| |
| sourceParent.replaceChild(decryptedFragment, element); |
| |
| return (contextDocument); |
| } |
| |
| |
| /** |
| * |
| * @param element |
| */ |
| private Document decryptElementContent(Element element) throws |
| XMLEncryptionException { |
| Element e = (Element) element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_ENCRYPTEDDATA).item(0); |
| |
| if (null == e) { |
| throw new XMLEncryptionException("No EncryptedData child element."); |
| } |
| |
| return (decryptElement(e)); |
| } |
| |
| |
| /** |
| * Creates an <code>EncryptedData</code> <code>Element</code>. |
| * |
| * @param text the Base 64 encoded, encrypted text to wrap in the |
| * <code>EncryptedData</code>. |
| * @return the <code>EncryptedData</code> <code>Element</code>. |
| * |
| * <!-- |
| * <EncryptedData Id[OPT] Type[OPT] MimeType[OPT] Encoding[OPT]> |
| * <EncryptionMethod/>[OPT] |
| * <ds:KeyInfo>[OPT] |
| * <EncryptedKey/>[OPT] |
| * <AgreementMethod/>[OPT] |
| * <ds:KeyName/>[OPT] |
| * <ds:RetrievalMethod/>[OPT] |
| * <ds:[MUL]/>[OPT] |
| * </ds:KeyInfo> |
| * <CipherData>[MAN] |
| * <CipherValue/> XOR <CipherReference/> |
| * </CipherData> |
| * <EncryptionProperties/>[OPT] |
| * </EncryptedData> |
| * --> |
| */ |
| private EncryptedData createEncryptedData(int type, String value) throws |
| XMLEncryptionException { |
| EncryptedData result = null; |
| CipherData data = null; |
| |
| switch (type) { |
| case CipherData.REFERENCE_TYPE: |
| String referenceUri = null; |
| try { |
| referenceUri = new URI(value).toString(); |
| } catch (URI.MalformedURIException mfue) { |
| throw new XMLEncryptionException("empty", mfue); |
| } |
| CipherReference cipherReference = factory.newCipherReference( |
| referenceUri); |
| data = factory.newCipherData(type); |
| data.setCipherReference(cipherReference); |
| result = factory.newEncryptedData(data); |
| case CipherData.VALUE_TYPE: |
| CipherValue cipherValue = factory.newCipherValue(value); |
| data = factory.newCipherData(type); |
| data.setCipherValue(cipherValue); |
| result = factory.newEncryptedData(data); |
| } |
| |
| return (result); |
| } |
| |
| /** |
| * Converts <code>String</code>s into <code>Node</code>s and visa versa. |
| * <p> |
| * <b>NOTE:</b> For internal use only. |
| * |
| * @author Axl Mattheus |
| */ |
| private class Serializer { |
| private OutputFormat format; |
| private XMLSerializer serializer; |
| |
| /** |
| * Initialize the <code>XMLSerializer</code> with the specified context |
| * <code>Document</code>. |
| * |
| * @param document the context <code>Document</code>. |
| */ |
| Serializer() { |
| format = new OutputFormat(); |
| format.setEncoding("UTF-8"); |
| format.setOmitDocumentType(true); |
| format.setOmitXMLDeclaration(true); |
| format.setPreserveSpace(true); |
| } |
| |
| /** |
| * Returns a <code>String</code> representation of the specified |
| * <code>Document</code>. |
| * |
| * @param doc the <code>Document</code> to serialize. |
| * @return the <code>String</code> representation of the serilaized |
| * <code>Document</code>. |
| * @throws |
| */ |
| String serialize(Document document) throws XMLEncryptionException { |
| StringWriter output = new StringWriter(); |
| serializer = new XMLSerializer(output, format); |
| |
| try { |
| serializer.serialize(document); |
| } catch (IOException ioe) { |
| throw new XMLEncryptionException("empty", ioe); |
| } |
| |
| return (output.toString()); |
| } |
| |
| /** |
| * Returns a <code>String</code> representation of the specified |
| * <code>Element</code>. |
| * |
| * @param doc the <code>Element</code> to serialize. |
| * @return the <code>String</code> representation of the serilaized |
| * <code>Element</code>. |
| * @throws |
| */ |
| String serialize(Element element) throws XMLEncryptionException { |
| StringWriter output = new StringWriter(); |
| serializer = new XMLSerializer(output, format); |
| |
| try { |
| serializer.serialize(element); |
| } catch (IOException ioe) { |
| throw new XMLEncryptionException("empty", ioe); |
| } |
| |
| return (output.toString()); |
| } |
| |
| /** |
| * Returns a <code>String</code> representation of the specified |
| * <code>NodeList</code>. |
| * |
| * @param doc the <code>NodeList</code> to serialize. |
| * @return the <code>String</code> representation of the serilaized |
| * <code>NodeList</code>. |
| * @throws |
| */ |
| String serialize(NodeList content) throws XMLEncryptionException { |
| StringWriter output = new StringWriter(); |
| serializer = new XMLSerializer(output, format); |
| |
| try { |
| for (int i =0; i < content.getLength(); i++) { |
| Node n = content.item(i); |
| if ((null != n) && (n.getNodeType() == Node.ELEMENT_NODE)) { |
| serializer.serialize((Element) n); |
| } |
| } |
| } catch (IOException ioe) { |
| throw new XMLEncryptionException("empty", ioe); |
| } |
| |
| return (output.toString()); |
| } |
| |
| /** |
| * |
| */ |
| DocumentFragment deserialize(String source, Element ctx) throws XMLEncryptionException { |
| DocumentFragment result; |
| final String tagname = "fragment"; |
| |
| // Create the context to parse the document against |
| StringBuffer sb; |
| |
| sb = new StringBuffer(); |
| sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><"+tagname); |
| |
| // Run through each node up to the document node and find any |
| // xmlns: nodes |
| |
| Node wk = ctx; |
| |
| while (wk != null) { |
| |
| NamedNodeMap atts = wk.getAttributes(); |
| int length; |
| if (atts != null) |
| length = atts.getLength(); |
| else |
| length = 0; |
| |
| for (int i = 0 ; i < length ; ++i) { |
| Node att = atts.item(i); |
| if (att.getNodeName().startsWith("xmlns:") || |
| att.getNodeName() == "xmlns") { |
| |
| // Check to see if this node has already been found |
| Node p = ctx; |
| boolean found = false; |
| while (p != wk) { |
| NamedNodeMap tstAtts = p.getAttributes(); |
| if (tstAtts != null && |
| tstAtts.getNamedItem(att.getNodeName()) != null) { |
| found = true; |
| break; |
| } |
| p = p.getParentNode(); |
| } |
| if (found == false) { |
| |
| // This is an attribute node |
| sb.append(" " + att.getNodeName() + "=\"" + |
| att.getNodeValue() + "\""); |
| } |
| } |
| } |
| wk = wk.getParentNode(); |
| } |
| sb.append(">" + source + "</" + tagname + ">"); |
| String fragment = sb.toString(); |
| |
| try { |
| DocumentBuilderFactory dbf = |
| DocumentBuilderFactory.newInstance(); |
| dbf.setNamespaceAware(true); |
| dbf.setAttribute("http://xml.org/sax/features/namespaces", Boolean.TRUE); |
| DocumentBuilder db = dbf.newDocumentBuilder(); |
| Document d = db.parse( |
| new InputSource(new StringReader(fragment))); |
| |
| Element fragElt = (Element) contextDocument.importNode( |
| d.getDocumentElement(), true); |
| result = contextDocument.createDocumentFragment(); |
| Node child = fragElt.getFirstChild(); |
| while (child != null) { |
| fragElt.removeChild(child); |
| result.appendChild(child); |
| child = fragElt.getFirstChild(); |
| } |
| String outp = serialize(d); |
| |
| } catch (SAXException se) { |
| throw new XMLEncryptionException("empty", se); |
| } catch (ParserConfigurationException pce) { |
| throw new XMLEncryptionException("empty", pce); |
| } catch (IOException ioe) { |
| throw new XMLEncryptionException("empty", ioe); |
| } |
| |
| return (result); |
| } |
| } |
| |
| /** |
| * |
| * @author Axl Mattheus |
| */ |
| private class Factory { |
| /** |
| * |
| */ |
| AgreementMethod newAgreementMethod(String algorithm) throws |
| XMLEncryptionException { |
| return (new AgreementMethodImpl(algorithm)); |
| } |
| |
| /** |
| * |
| */ |
| CipherData newCipherData(int type) { |
| return (new CipherDataImpl(type)); |
| } |
| |
| /** |
| * |
| */ |
| CipherReference newCipherReference(String uri) throws |
| XMLEncryptionException { |
| return (new CipherReferenceImpl(uri)); |
| } |
| |
| /** |
| * |
| */ |
| CipherValue newCipherValue(String value) { |
| return (new CipherValueImpl(value)); |
| } |
| |
| /** |
| * |
| */ |
| CipherValue newCipherValue(byte[] value) { |
| return (new CipherValueImpl(value)); |
| } |
| |
| /** |
| * |
| */ |
| EncryptedData newEncryptedData(CipherData data) { |
| return (new EncryptedDataImpl(data)); |
| } |
| |
| /** |
| * |
| */ |
| EncryptedKey newEncryptedKey(CipherData data) { |
| return (new EncryptedKeyImpl(data)); |
| } |
| |
| /** |
| * |
| */ |
| EncryptionMethod newEncryptionMethod(String algorithm) throws |
| XMLEncryptionException { |
| return (new EncryptionMethodImpl(algorithm)); |
| } |
| |
| /** |
| * |
| */ |
| EncryptionProperties newEncryptionProperties() { |
| return (new EncryptionPropertiesImpl()); |
| } |
| |
| /** |
| * |
| */ |
| EncryptionProperty newEncryptionProperty() { |
| return (new EncryptionPropertyImpl()); |
| } |
| |
| /** |
| * |
| */ |
| ReferenceList newReferenceList(int type) { |
| return (new ReferenceList(type)); |
| } |
| |
| /** |
| * |
| */ |
| Transforms newTransforms() { |
| return (new TransformsImpl()); |
| } |
| |
| /** |
| * |
| */ |
| // <element name="AgreementMethod" type="xenc:AgreementMethodType"/> |
| // <complexType name="AgreementMethodType" mixed="true"> |
| // <sequence> |
| // <element name="KA-Nonce" minOccurs="0" type="base64Binary"/> |
| // <!-- <element ref="ds:DigestMethod" minOccurs="0"/> --> |
| // <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/> |
| // <element name="OriginatorKeyInfo" minOccurs="0" type="ds:KeyInfoType"/> |
| // <element name="RecipientKeyInfo" minOccurs="0" type="ds:KeyInfoType"/> |
| // </sequence> |
| // <attribute name="Algorithm" type="anyURI" use="required"/> |
| // </complexType> |
| AgreementMethod newAgreementMethod(Element element) throws |
| XMLEncryptionException { |
| if (null == element) { |
| //complain |
| } |
| |
| String algorithm = element.getAttributeNS(null, |
| EncryptionConstants._ATT_ALGORITHM); |
| AgreementMethod result = newAgreementMethod(algorithm); |
| |
| Element kaNonceElement = (Element) element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_KA_NONCE).item(0); |
| if (null != kaNonceElement) { |
| result.setKANonce(kaNonceElement.getNodeValue().getBytes()); |
| } |
| // TODO: /////////////////////////////////////////////////////////// |
| // Figure out how to make this pesky line work.. |
| // <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/> |
| |
| // TODO: /////////////////////////////////////////////////////////// |
| // Implement properly, implement a KeyInfo marshaler. |
| Element originatorKeyInfoElement = |
| (Element) element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_ORIGINATORKEYINFO).item(0); |
| if (null != originatorKeyInfoElement) { |
| result.setOriginatorKeyInfo(null); |
| } |
| |
| // TODO: /////////////////////////////////////////////////////////// |
| // Implement properly, implement a KeyInfo marshaler. |
| Element recipientKeyInfoElement = |
| (Element) element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_RECIPIENTKEYINFO).item(0); |
| if (null != recipientKeyInfoElement) { |
| result.setRecipientKeyInfo(null); |
| } |
| |
| return (result); |
| } |
| |
| /** |
| * |
| */ |
| // <element name='CipherData' type='xenc:CipherDataType'/> |
| // <complexType name='CipherDataType'> |
| // <choice> |
| // <element name='CipherValue' type='base64Binary'/> |
| // <element ref='xenc:CipherReference'/> |
| // </choice> |
| // </complexType> |
| CipherData newCipherData(Element element) throws |
| XMLEncryptionException { |
| if (null == element) { |
| // complain |
| } |
| |
| int type = 0; |
| Element e = null; |
| if (element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_CIPHERVALUE).getLength() > 0) { |
| type = CipherData.VALUE_TYPE; |
| e = (Element) element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_CIPHERVALUE).item(0); |
| } else if (element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_CIPHERREFERENCE).getLength() > 0) { |
| type = CipherData.REFERENCE_TYPE; |
| e = (Element) element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_CIPHERREFERENCE).item(0); |
| } |
| |
| CipherData result = newCipherData(type); |
| if (type == CipherData.VALUE_TYPE) { |
| result.setCipherValue(newCipherValue(e)); |
| } else if (type == CipherData.REFERENCE_TYPE) { |
| // |
| } |
| |
| return (result); |
| } |
| |
| /** |
| * |
| */ |
| // <element name='CipherReference' type='xenc:CipherReferenceType'/> |
| // <complexType name='CipherReferenceType'> |
| // <sequence> |
| // <element name='Transforms' type='xenc:TransformsType' minOccurs='0'/> |
| // </sequence> |
| // <attribute name='URI' type='anyURI' use='required'/> |
| // </complexType> |
| CipherReference newCipherReference(Element element) throws |
| XMLEncryptionException { |
| // NOTE: /////////////////////////////////////////////////////////// |
| // |
| // This operation will be implemented during November 2002. Until |
| //then, complain. |
| // TODO: Implement. |
| String uo = "This operation is not implemented in this release."; |
| throw new XMLEncryptionException("empty", |
| new UnsupportedOperationException(uo)); |
| } |
| |
| /** |
| * |
| */ |
| CipherValue newCipherValue(Element element) throws |
| XMLEncryptionException { |
| String value = element.getFirstChild().getNodeValue(); |
| |
| CipherValue result = newCipherValue(value); |
| |
| return (result); |
| } |
| |
| /** |
| * |
| */ |
| // <complexType name='EncryptedType' abstract='true'> |
| // <sequence> |
| // <element name='EncryptionMethod' type='xenc:EncryptionMethodType' |
| // minOccurs='0'/> |
| // <element ref='ds:KeyInfo' minOccurs='0'/> |
| // <element ref='xenc:CipherData'/> |
| // <element ref='xenc:EncryptionProperties' minOccurs='0'/> |
| // </sequence> |
| // <attribute name='Id' type='ID' use='optional'/> |
| // <attribute name='Type' type='anyURI' use='optional'/> |
| // <attribute name='MimeType' type='string' use='optional'/> |
| // <attribute name='Encoding' type='anyURI' use='optional'/> |
| // </complexType> |
| // <element name='EncryptedData' type='xenc:EncryptedDataType'/> |
| // <complexType name='EncryptedDataType'> |
| // <complexContent> |
| // <extension base='xenc:EncryptedType'/> |
| // </complexContent> |
| // </complexType> |
| EncryptedData newEncryptedData(Element element) throws |
| XMLEncryptionException { |
| EncryptedData result = null; |
| |
| Element dataElement = |
| (Element) element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_CIPHERDATA).item(0); |
| CipherData data = newCipherData(dataElement); |
| |
| result = newEncryptedData(data); |
| |
| try { |
| result.setId(element.getAttributeNS( |
| null, EncryptionConstants._ATT_ID)); |
| result.setType(new URI( |
| element.getAttributeNS( |
| null, EncryptionConstants._ATT_TYPE)).toString()); |
| result.setMimeType(element.getAttributeNS( |
| null, EncryptionConstants._ATT_MIMETYPE)); |
| result.setEncoding(new URI( |
| element.getAttributeNS( |
| null, Constants._ATT_ENCODING)).toString()); |
| } catch (URI.MalformedURIException mfue) { |
| // do nothing |
| } |
| |
| Element encryptionMethodElement = |
| (Element) element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_ENCRYPTIONMETHOD).item(0); |
| if (null != encryptionMethodElement) { |
| result.setEncryptionMethod(newEncryptionMethod( |
| encryptionMethodElement)); |
| } |
| |
| // BFL 16/7/03 - simple implementation |
| // TODO: Work out how to handle relative URI |
| |
| Element keyInfoElement = |
| (Element) element.getElementsByTagNameNS( |
| Constants.SignatureSpecNS, Constants._TAG_KEYINFO).item(0); |
| if (null != keyInfoElement) { |
| try { |
| result.setKeyInfo(new KeyInfo(keyInfoElement, null)); |
| } catch (XMLSecurityException xse) { |
| throw new XMLEncryptionException("Error loading Key Info", |
| xse); |
| } |
| } |
| |
| // TODO: Implement |
| Element encryptionPropertiesElement = |
| (Element) element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_ENCRYPTIONPROPERTIES).item(0); |
| if (null != encryptionPropertiesElement) { |
| result.setEncryptionProperties( |
| newEncryptionProperties(encryptionPropertiesElement)); |
| } |
| |
| return (result); |
| } |
| |
| /** |
| * |
| */ |
| // <complexType name='EncryptedType' abstract='true'> |
| // <sequence> |
| // <element name='EncryptionMethod' type='xenc:EncryptionMethodType' |
| // minOccurs='0'/> |
| // <element ref='ds:KeyInfo' minOccurs='0'/> |
| // <element ref='xenc:CipherData'/> |
| // <element ref='xenc:EncryptionProperties' minOccurs='0'/> |
| // </sequence> |
| // <attribute name='Id' type='ID' use='optional'/> |
| // <attribute name='Type' type='anyURI' use='optional'/> |
| // <attribute name='MimeType' type='string' use='optional'/> |
| // <attribute name='Encoding' type='anyURI' use='optional'/> |
| // </complexType> |
| // <element name='EncryptedKey' type='xenc:EncryptedKeyType'/> |
| // <complexType name='EncryptedKeyType'> |
| // <complexContent> |
| // <extension base='xenc:EncryptedType'> |
| // <sequence> |
| // <element ref='xenc:ReferenceList' minOccurs='0'/> |
| // <element name='CarriedKeyName' type='string' minOccurs='0'/> |
| // </sequence> |
| // <attribute name='Recipient' type='string' use='optional'/> |
| // </extension> |
| // </complexContent> |
| // </complexType> |
| EncryptedKey newEncryptedKey(Element element) throws |
| XMLEncryptionException { |
| EncryptedKey result = null; |
| |
| Element dataElement = |
| (Element) element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_CIPHERDATA).item(0); |
| CipherData data = newCipherData(dataElement); |
| result = newEncryptedKey(data); |
| |
| try { |
| result.setId(element.getAttributeNS( |
| null, EncryptionConstants._ATT_ID)); |
| result.setType(new URI( |
| element.getAttributeNS( |
| null, EncryptionConstants._ATT_TYPE)).toString()); |
| result.setMimeType(element.getAttributeNS( |
| null, EncryptionConstants._ATT_MIMETYPE)); |
| result.setEncoding(new URI( |
| element.getAttributeNS( |
| null, Constants._ATT_ENCODING)).toString()); |
| result.setRecipient(element.getAttributeNS( |
| null, EncryptionConstants._ATT_RECIPIENT)); |
| } catch (URI.MalformedURIException mfue) { |
| // do nothing |
| } |
| |
| Element encryptionMethodElement = |
| (Element) element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_ENCRYPTIONMETHOD).item(0); |
| if (null != encryptionMethodElement) { |
| result.setEncryptionMethod(newEncryptionMethod( |
| encryptionMethodElement)); |
| } |
| |
| // TODO: Implement |
| Element keyInfoElement = |
| (Element) element.getElementsByTagNameNS( |
| Constants.SignatureSpecNS, Constants._TAG_KEYINFO).item(0); |
| if (null != keyInfoElement) { |
| result.setKeyInfo(null); |
| } |
| |
| // TODO: Implement |
| Element encryptionPropertiesElement = |
| (Element) element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_ENCRYPTIONPROPERTIES).item(0); |
| if (null != encryptionPropertiesElement) { |
| result.setEncryptionProperties( |
| newEncryptionProperties(encryptionPropertiesElement)); |
| } |
| |
| Element referenceListElement = |
| (Element) element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_REFERENCELIST).item(0); |
| if (null != referenceListElement) { |
| result.setReferenceList(newReferenceList(referenceListElement)); |
| } |
| |
| Element carriedNameElement = |
| (Element) element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_CARRIEDKEYNAME).item(0); |
| if (null != carriedNameElement) { |
| result.setCarriedName(carriedNameElement.getNodeValue()); |
| } |
| |
| return (result); |
| } |
| |
| /** |
| * |
| */ |
| // <complexType name='EncryptionMethodType' mixed='true'> |
| // <sequence> |
| // <element name='KeySize' minOccurs='0' type='xenc:KeySizeType'/> |
| // <element name='OAEPparams' minOccurs='0' type='base64Binary'/> |
| // <any namespace='##other' minOccurs='0' maxOccurs='unbounded'/> |
| // </sequence> |
| // <attribute name='Algorithm' type='anyURI' use='required'/> |
| // </complexType> |
| EncryptionMethod newEncryptionMethod(Element element) throws |
| XMLEncryptionException { |
| String algorithm = element.getAttributeNS( |
| null, EncryptionConstants._ATT_ALGORITHM); |
| EncryptionMethod result = newEncryptionMethod(algorithm); |
| |
| Element keySizeElement = |
| (Element) element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_KEYSIZE).item(0); |
| if (null != keySizeElement) { |
| result.setKeySize( |
| Integer.valueOf(keySizeElement.getNodeValue()).intValue()); |
| } |
| |
| Element oaepParamsElement = |
| (Element) element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_OAEPPARAMS).item(0); |
| if (null != oaepParamsElement) { |
| result.setOAEPparams( |
| oaepParamsElement.getNodeValue().getBytes()); |
| } |
| |
| // TODO: Make this mess work |
| // <any namespace='##other' minOccurs='0' maxOccurs='unbounded'/> |
| |
| return (result); |
| } |
| |
| /** |
| * |
| */ |
| // <element name='EncryptionProperties' type='xenc:EncryptionPropertiesType'/> |
| // <complexType name='EncryptionPropertiesType'> |
| // <sequence> |
| // <element ref='xenc:EncryptionProperty' maxOccurs='unbounded'/> |
| // </sequence> |
| // <attribute name='Id' type='ID' use='optional'/> |
| // </complexType> |
| EncryptionProperties newEncryptionProperties(Element element) throws |
| XMLEncryptionException { |
| EncryptionProperties result = newEncryptionProperties(); |
| |
| result.setId(element.getAttributeNS( |
| null, EncryptionConstants._ATT_ID)); |
| |
| NodeList encryptionPropertyList = |
| element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_ENCRYPTIONPROPERTY); |
| for(int i = 0; i < encryptionPropertyList.getLength(); i++) { |
| Node n = encryptionPropertyList.item(i); |
| if (null != n) { |
| result.addEncryptionProperty( |
| newEncryptionProperty((Element) n)); |
| } |
| } |
| |
| return (result); |
| } |
| |
| /** |
| * |
| */ |
| // <element name='EncryptionProperty' type='xenc:EncryptionPropertyType'/> |
| // <complexType name='EncryptionPropertyType' mixed='true'> |
| // <choice maxOccurs='unbounded'> |
| // <any namespace='##other' processContents='lax'/> |
| // </choice> |
| // <attribute name='Target' type='anyURI' use='optional'/> |
| // <attribute name='Id' type='ID' use='optional'/> |
| // <anyAttribute namespace="http://www.w3.org/XML/1998/namespace"/> |
| // </complexType> |
| EncryptionProperty newEncryptionProperty(Element element) throws |
| XMLEncryptionException { |
| EncryptionProperty result = newEncryptionProperty(); |
| |
| try { |
| result.setTarget(new URI( |
| element.getAttributeNS( |
| null, EncryptionConstants._ATT_TARGET)).toString()); |
| } catch (URI.MalformedURIException mfue) { |
| // do nothing |
| } |
| result.setId(element.getAttributeNS( |
| null, EncryptionConstants._ATT_ID)); |
| // TODO: Make this lot work... |
| // <anyAttribute namespace="http://www.w3.org/XML/1998/namespace"/> |
| |
| // TODO: Make this work... |
| // <any namespace='##other' processContents='lax'/> |
| |
| return (result); |
| } |
| |
| /** |
| * |
| */ |
| // <element name='ReferenceList'> |
| // <complexType> |
| // <choice minOccurs='1' maxOccurs='unbounded'> |
| // <element name='DataReference' type='xenc:ReferenceType'/> |
| // <element name='KeyReference' type='xenc:ReferenceType'/> |
| // </choice> |
| // </complexType> |
| // </element> |
| ReferenceList newReferenceList(Element element) throws |
| XMLEncryptionException { |
| int type = 0; |
| if (null != element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_DATAREFERENCE).item(0)) { |
| type = ReferenceList.DATA_REFERENCE; |
| } else if (null != element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_KEYREFERENCE).item(0)) { |
| type = ReferenceList.KEY_REFERENCE; |
| } else { |
| // complain |
| } |
| |
| ReferenceList result = newReferenceList(type); |
| NodeList list = null; |
| switch (type) { |
| case ReferenceList.DATA_REFERENCE: |
| list = element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_DATAREFERENCE); |
| for (int i = 0; i < list.getLength() ; i++) { |
| String uri = null; |
| try { |
| uri = new URI( |
| ((Element) list.item(0)).getNodeValue()).toString(); |
| } catch (URI.MalformedURIException mfue) { |
| } |
| result.add(ReferenceList.newDataReference(uri)); |
| } |
| case ReferenceList.KEY_REFERENCE: |
| list = element.getElementsByTagNameNS( |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_KEYREFERENCE); |
| for (int i = 0; i < list.getLength() ; i++) { |
| String uri = null; |
| try { |
| uri = new URI( |
| ((Element) list.item(0)).getNodeValue()).toString(); |
| } catch (URI.MalformedURIException mfue) { |
| } |
| result.add(ReferenceList.newKeyReference(uri)); |
| } |
| } |
| |
| return (result); |
| } |
| |
| /** |
| * |
| */ |
| Transforms newTransforms(Element element) { |
| return (null); |
| } |
| |
| /** |
| * |
| */ |
| Element toElement(AgreementMethod agreementMethod) { |
| return ((AgreementMethodImpl) agreementMethod).toElement(); |
| } |
| |
| /** |
| * |
| */ |
| Element toElement(CipherData cipherData) { |
| return ((CipherDataImpl) cipherData).toElement(); |
| } |
| |
| /** |
| * |
| */ |
| Element toElement(CipherReference cipherReference) { |
| return ((CipherReferenceImpl) cipherReference).toElement(); |
| } |
| |
| /** |
| * |
| */ |
| Element toElement(CipherValue cipherValue) { |
| return ((CipherValueImpl) cipherValue).toElement(); |
| } |
| |
| /** |
| * |
| */ |
| Element toElement(EncryptedData encryptedData) { |
| return ((EncryptedDataImpl) encryptedData).toElement(); |
| } |
| |
| /** |
| * |
| */ |
| Element toElement(EncryptedKey encryptedKey) { |
| return ((EncryptedKeyImpl) encryptedKey).toElement(); |
| } |
| |
| /** |
| * |
| */ |
| Element toElement(EncryptionMethod encryptionMethod) { |
| return ((EncryptionMethodImpl) encryptionMethod).toElement(); |
| } |
| |
| /** |
| * |
| */ |
| Element toElement(EncryptionProperties encryptionProperties) { |
| return ((EncryptionPropertiesImpl) encryptionProperties).toElement(); |
| } |
| |
| /** |
| * |
| */ |
| Element toElement(EncryptionProperty encryptionProperty) { |
| return ((EncryptionPropertyImpl) encryptionProperty).toElement(); |
| } |
| |
| Element toElement(ReferenceList referenceList) { |
| // NOTE: /////////////////////////////////////////////////////////// |
| // TODO: Complete |
| return (null); |
| } |
| |
| /** |
| * |
| */ |
| Element toElement(Transforms transforms) { |
| return ((TransformsImpl) transforms).toElement(); |
| } |
| |
| // <element name="AgreementMethod" type="xenc:AgreementMethodType"/> |
| // <complexType name="AgreementMethodType" mixed="true"> |
| // <sequence> |
| // <element name="KA-Nonce" minOccurs="0" type="base64Binary"/> |
| // <!-- <element ref="ds:DigestMethod" minOccurs="0"/> --> |
| // <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/> |
| // <element name="OriginatorKeyInfo" minOccurs="0" type="ds:KeyInfoType"/> |
| // <element name="RecipientKeyInfo" minOccurs="0" type="ds:KeyInfoType"/> |
| // </sequence> |
| // <attribute name="Algorithm" type="anyURI" use="required"/> |
| // </complexType> |
| private class AgreementMethodImpl implements AgreementMethod { |
| private byte[] kaNonce = null; |
| private List agreementMethodInformation = null; |
| private KeyInfo originatorKeyInfo = null; |
| private KeyInfo recipientKeyInfo = null; |
| private String algorithmURI = null; |
| |
| public AgreementMethodImpl(String algorithm) { |
| agreementMethodInformation = new LinkedList(); |
| URI tmpAlgorithm = null; |
| try { |
| tmpAlgorithm = new URI(algorithm); |
| } catch (URI.MalformedURIException fmue) { |
| //complain? |
| } |
| algorithmURI = tmpAlgorithm.toString(); |
| } |
| |
| public byte[] getKANonce() { |
| return (kaNonce); |
| } |
| |
| public void setKANonce(byte[] kanonce) { |
| kaNonce = kanonce; |
| } |
| |
| public Iterator getAgreementMethodInformation() { |
| return (agreementMethodInformation.iterator()); |
| } |
| |
| public void addAgreementMethodInformation(Element info) { |
| agreementMethodInformation.add(info); |
| } |
| |
| public void revoveAgreementMethodInformation(Element info) { |
| agreementMethodInformation.remove(info); |
| } |
| |
| public KeyInfo getOriginatorKeyInfo() { |
| return (originatorKeyInfo); |
| } |
| |
| public void setOriginatorKeyInfo(KeyInfo keyInfo) { |
| originatorKeyInfo = keyInfo; |
| } |
| |
| public KeyInfo getRecipientKeyInfo() { |
| return (recipientKeyInfo); |
| } |
| |
| public void setRecipientKeyInfo(KeyInfo keyInfo) { |
| recipientKeyInfo = keyInfo; |
| } |
| |
| public String getAlgorithm() { |
| return (algorithmURI); |
| } |
| |
| public void setAlgorithm(String algorithm) { |
| URI tmpAlgorithm = null; |
| try { |
| tmpAlgorithm = new URI(algorithm); |
| } catch (URI.MalformedURIException mfue) { |
| //complain |
| } |
| algorithm = tmpAlgorithm.toString(); |
| } |
| |
| // <element name="AgreementMethod" type="xenc:AgreementMethodType"/> |
| // <complexType name="AgreementMethodType" mixed="true"> |
| // <sequence> |
| // <element name="KA-Nonce" minOccurs="0" type="base64Binary"/> |
| // <!-- <element ref="ds:DigestMethod" minOccurs="0"/> --> |
| // <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/> |
| // <element name="OriginatorKeyInfo" minOccurs="0" type="ds:KeyInfoType"/> |
| // <element name="RecipientKeyInfo" minOccurs="0" type="ds:KeyInfoType"/> |
| // </sequence> |
| // <attribute name="Algorithm" type="anyURI" use="required"/> |
| // </complexType> |
| Element toElement() { |
| Element result = ElementProxy.createElementForFamily( |
| contextDocument, |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_AGREEMENTMETHOD); |
| result.setAttributeNS( |
| null, EncryptionConstants._ATT_ALGORITHM, algorithmURI); |
| if (null != kaNonce) { |
| result.appendChild( |
| ElementProxy.createElementForFamily( |
| contextDocument, |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_KA_NONCE)).appendChild( |
| contextDocument.createTextNode(new String(kaNonce))); |
| } |
| if (!agreementMethodInformation.isEmpty()) { |
| Iterator itr = agreementMethodInformation.iterator(); |
| while (itr.hasNext()) { |
| result.appendChild((Element) itr.next()); |
| } |
| } |
| if (null != originatorKeyInfo) { |
| // TODO: complete |
| } |
| if (null != recipientKeyInfo) { |
| // TODO: complete |
| } |
| |
| return (result); |
| } |
| } |
| |
| // <element name='CipherData' type='xenc:CipherDataType'/> |
| // <complexType name='CipherDataType'> |
| // <choice> |
| // <element name='CipherValue' type='base64Binary'/> |
| // <element ref='xenc:CipherReference'/> |
| // </choice> |
| // </complexType> |
| private class CipherDataImpl implements CipherData { |
| private static final String valueMessage = |
| "Data type is reference type."; |
| private static final String referenceMessage = |
| "Data type is value type."; |
| private CipherValue cipherValue = null; |
| private CipherReference cipherReference = null; |
| private int cipherType = Integer.MIN_VALUE; |
| |
| public CipherDataImpl(int type) { |
| cipherType = type; |
| } |
| |
| public CipherValue getCipherValue() { |
| return (cipherValue); |
| } |
| |
| public void setCipherValue(CipherValue value) throws |
| XMLEncryptionException { |
| if (cipherType == REFERENCE_TYPE) { |
| throw new XMLEncryptionException("empty", |
| new UnsupportedOperationException(valueMessage)); |
| } |
| |
| cipherValue = value; |
| } |
| |
| public CipherReference getCipherReference() { |
| return (cipherReference); |
| } |
| |
| public void setCipherReference(CipherReference reference) throws |
| XMLEncryptionException { |
| if (cipherType == VALUE_TYPE) { |
| throw new XMLEncryptionException("empty", |
| new UnsupportedOperationException(referenceMessage)); |
| } |
| |
| cipherReference = reference; |
| } |
| |
| public int getDataType() { |
| return (cipherType); |
| } |
| |
| // <element name='CipherData' type='xenc:CipherDataType'/> |
| // <complexType name='CipherDataType'> |
| // <choice> |
| // <element name='CipherValue' type='base64Binary'/> |
| // <element ref='xenc:CipherReference'/> |
| // </choice> |
| // </complexType> |
| Element toElement() { |
| Element result = ElementProxy.createElementForFamily( |
| contextDocument, |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_CIPHERDATA); |
| if (cipherType == VALUE_TYPE) { |
| result.appendChild( |
| ((CipherValueImpl) cipherValue).toElement()); |
| } else if (cipherType == REFERENCE_TYPE) { |
| result.appendChild( |
| ((CipherReferenceImpl) cipherReference).toElement()); |
| } else { |
| // complain |
| } |
| |
| return (result); |
| } |
| } |
| |
| // <element name='CipherReference' type='xenc:CipherReferenceType'/> |
| // <complexType name='CipherReferenceType'> |
| // <sequence> |
| // <element name='Transforms' type='xenc:TransformsType' minOccurs='0'/> |
| // </sequence> |
| // <attribute name='URI' type='anyURI' use='required'/> |
| // </complexType> |
| private class CipherReferenceImpl implements CipherReference { |
| private String referenceURI = null; |
| private Transforms referenceTransforms = null; |
| |
| public CipherReferenceImpl(String uri) { |
| URI tmpReferenceURI = null; |
| try { |
| tmpReferenceURI = new URI(uri); |
| } catch (URI.MalformedURIException mfue) { |
| // complain |
| } |
| referenceURI = tmpReferenceURI.toString(); |
| } |
| |
| public String getURI() { |
| return (referenceURI); |
| } |
| |
| public Transforms getTransforms() { |
| return (referenceTransforms); |
| } |
| |
| public void setTransforms(Transforms transforms) { |
| referenceTransforms = transforms; |
| } |
| |
| // <element name='CipherReference' type='xenc:CipherReferenceType'/> |
| // <complexType name='CipherReferenceType'> |
| // <sequence> |
| // <element name='Transforms' type='xenc:TransformsType' minOccurs='0'/> |
| // </sequence> |
| // <attribute name='URI' type='anyURI' use='required'/> |
| // </complexType> |
| Element toElement() { |
| Element result = ElementProxy.createElementForFamily( |
| contextDocument, |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_CIPHERREFERENCE); |
| result.setAttributeNS( |
| null, EncryptionConstants._ATT_URI, referenceURI); |
| if (null != referenceTransforms) { |
| result.appendChild( |
| ((TransformsImpl) referenceTransforms).toElement()); |
| } |
| |
| return (result); |
| } |
| } |
| |
| private class CipherValueImpl implements CipherValue { |
| private byte[] cipherValue = null; |
| |
| public CipherValueImpl(byte[] value) { |
| cipherValue = value; |
| } |
| |
| public CipherValueImpl(String value) { |
| cipherValue = value.getBytes(); |
| } |
| |
| public byte[] getValue() { |
| return (cipherValue); |
| } |
| |
| public void setValue(byte[] value) { |
| cipherValue = value; |
| } |
| |
| public void setValue(String value) { |
| cipherValue = value.getBytes(); |
| } |
| |
| Element toElement() { |
| Element result = ElementProxy.createElementForFamily( |
| contextDocument, EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_CIPHERVALUE); |
| result.appendChild(contextDocument.createTextNode( |
| new String(cipherValue))); |
| |
| return (result); |
| } |
| } |
| |
| // <complexType name='EncryptedType' abstract='true'> |
| // <sequence> |
| // <element name='EncryptionMethod' type='xenc:EncryptionMethodType' |
| // minOccurs='0'/> |
| // <element ref='ds:KeyInfo' minOccurs='0'/> |
| // <element ref='xenc:CipherData'/> |
| // <element ref='xenc:EncryptionProperties' minOccurs='0'/> |
| // </sequence> |
| // <attribute name='Id' type='ID' use='optional'/> |
| // <attribute name='Type' type='anyURI' use='optional'/> |
| // <attribute name='MimeType' type='string' use='optional'/> |
| // <attribute name='Encoding' type='anyURI' use='optional'/> |
| // </complexType> |
| // <element name='EncryptedData' type='xenc:EncryptedDataType'/> |
| // <complexType name='EncryptedDataType'> |
| // <complexContent> |
| // <extension base='xenc:EncryptedType'/> |
| // </complexContent> |
| // </complexType> |
| private class EncryptedDataImpl extends EncryptedTypeImpl implements |
| EncryptedData { |
| public EncryptedDataImpl(CipherData data) { |
| super(data); |
| } |
| |
| // <complexType name='EncryptedType' abstract='true'> |
| // <sequence> |
| // <element name='EncryptionMethod' type='xenc:EncryptionMethodType' |
| // minOccurs='0'/> |
| // <element ref='ds:KeyInfo' minOccurs='0'/> |
| // <element ref='xenc:CipherData'/> |
| // <element ref='xenc:EncryptionProperties' minOccurs='0'/> |
| // </sequence> |
| // <attribute name='Id' type='ID' use='optional'/> |
| // <attribute name='Type' type='anyURI' use='optional'/> |
| // <attribute name='MimeType' type='string' use='optional'/> |
| // <attribute name='Encoding' type='anyURI' use='optional'/> |
| // </complexType> |
| // <element name='EncryptedData' type='xenc:EncryptedDataType'/> |
| // <complexType name='EncryptedDataType'> |
| // <complexContent> |
| // <extension base='xenc:EncryptedType'/> |
| // </complexContent> |
| // </complexType> |
| Element toElement() { |
| Element result = ElementProxy.createElementForFamily( |
| contextDocument, EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_ENCRYPTEDDATA); |
| |
| if (null != super.getId()) { |
| result.setAttributeNS( |
| null, EncryptionConstants._ATT_ID, super.getId()); |
| } |
| if (null != super.getType()) { |
| result.setAttributeNS( |
| null, EncryptionConstants._ATT_TYPE, |
| super.getType().toString()); |
| } |
| if (null != super.getMimeType()) { |
| result.setAttributeNS( |
| null, EncryptionConstants._ATT_MIMETYPE, |
| super.getMimeType()); |
| } |
| if (null != super.getEncoding()) { |
| result.setAttributeNS( |
| null, EncryptionConstants._ATT_ENCODING, |
| super.getEncoding().toString()); |
| } |
| if (null != super.getEncryptionMethod()) { |
| result.appendChild(((EncryptionMethodImpl) |
| super.getEncryptionMethod()).toElement()); |
| } |
| if (null != super.getKeyInfo()) { |
| // TODO: complete |
| } |
| result.appendChild( |
| ((CipherDataImpl) super.getCipherData()).toElement()); |
| if (null != super.getEncryptionProperties()) { |
| result.appendChild(((EncryptionPropertiesImpl) |
| super.getEncryptionProperties()).toElement()); |
| } |
| |
| return (result); |
| } |
| } |
| |
| // <complexType name='EncryptedType' abstract='true'> |
| // <sequence> |
| // <element name='EncryptionMethod' type='xenc:EncryptionMethodType' |
| // minOccurs='0'/> |
| // <element ref='ds:KeyInfo' minOccurs='0'/> |
| // <element ref='xenc:CipherData'/> |
| // <element ref='xenc:EncryptionProperties' minOccurs='0'/> |
| // </sequence> |
| // <attribute name='Id' type='ID' use='optional'/> |
| // <attribute name='Type' type='anyURI' use='optional'/> |
| // <attribute name='MimeType' type='string' use='optional'/> |
| // <attribute name='Encoding' type='anyURI' use='optional'/> |
| // </complexType> |
| // <element name='EncryptedKey' type='xenc:EncryptedKeyType'/> |
| // <complexType name='EncryptedKeyType'> |
| // <complexContent> |
| // <extension base='xenc:EncryptedType'> |
| // <sequence> |
| // <element ref='xenc:ReferenceList' minOccurs='0'/> |
| // <element name='CarriedKeyName' type='string' minOccurs='0'/> |
| // </sequence> |
| // <attribute name='Recipient' type='string' use='optional'/> |
| // </extension> |
| // </complexContent> |
| // </complexType> |
| private class EncryptedKeyImpl extends EncryptedTypeImpl implements |
| EncryptedKey { |
| private String keyRecipient = null; |
| private ReferenceList referenceList = null; |
| private String carriedName = null; |
| |
| public EncryptedKeyImpl(CipherData data) { |
| super(data); |
| } |
| |
| public String getRecipient() { |
| return (keyRecipient); |
| } |
| |
| public void setRecipient(String recipient) { |
| keyRecipient = recipient; |
| } |
| |
| public ReferenceList getReferenceList() { |
| return (referenceList); |
| } |
| |
| public void setReferenceList(ReferenceList list) { |
| referenceList = list; |
| } |
| |
| public String getCarriedName() { |
| return (carriedName); |
| } |
| |
| public void setCarriedName(String name) { |
| carriedName = name; |
| } |
| |
| // <complexType name='EncryptedType' abstract='true'> |
| // <sequence> |
| // <element name='EncryptionMethod' type='xenc:EncryptionMethodType' |
| // minOccurs='0'/> |
| // <element ref='ds:KeyInfo' minOccurs='0'/> |
| // <element ref='xenc:CipherData'/> |
| // <element ref='xenc:EncryptionProperties' minOccurs='0'/> |
| // </sequence> |
| // <attribute name='Id' type='ID' use='optional'/> |
| // <attribute name='Type' type='anyURI' use='optional'/> |
| // <attribute name='MimeType' type='string' use='optional'/> |
| // <attribute name='Encoding' type='anyURI' use='optional'/> |
| // </complexType> |
| // <element name='EncryptedKey' type='xenc:EncryptedKeyType'/> |
| // <complexType name='EncryptedKeyType'> |
| // <complexContent> |
| // <extension base='xenc:EncryptedType'> |
| // <sequence> |
| // <element ref='xenc:ReferenceList' minOccurs='0'/> |
| // <element name='CarriedKeyName' type='string' minOccurs='0'/> |
| // </sequence> |
| // <attribute name='Recipient' type='string' use='optional'/> |
| // </extension> |
| // </complexContent> |
| // </complexType> |
| Element toElement() { |
| Element result = ElementProxy.createElementForFamily( |
| contextDocument, EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_ENCRYPTEDDATA); |
| |
| if (null != super.getId()) { |
| result.setAttributeNS( |
| null, EncryptionConstants._ATT_ID, super.getId()); |
| } |
| if (null != super.getType()) { |
| result.setAttributeNS( |
| null, EncryptionConstants._ATT_TYPE, |
| super.getType().toString()); |
| } |
| if (null != super.getMimeType()) { |
| result.setAttributeNS(null, |
| EncryptionConstants._ATT_MIMETYPE, super.getMimeType()); |
| } |
| if (null != super.getEncoding()) { |
| result.setAttributeNS(null, Constants._ATT_ENCODING, |
| super.getEncoding().toString()); |
| } |
| if (null != getRecipient()) { |
| result.setAttributeNS(null, |
| EncryptionConstants._ATT_RECIPIENT, getRecipient()); |
| } |
| if (null != super.getEncryptionMethod()) { |
| result.appendChild(((EncryptionMethodImpl) |
| super.getEncryptionMethod()).toElement()); |
| } |
| if (null != super.getKeyInfo()) { |
| // TODO: complete |
| } |
| result.appendChild( |
| ((CipherDataImpl) super.getCipherData()).toElement()); |
| if (null != super.getEncryptionProperties()) { |
| result.appendChild(((EncryptionPropertiesImpl) |
| super.getEncryptionProperties()).toElement()); |
| } |
| if (!referenceList.isEmpty()) { |
| // TODO: complete |
| } |
| if (null != carriedName) { |
| result.appendChild( |
| ElementProxy.createElementForFamily(contextDocument, |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_CARRIEDKEYNAME).appendChild( |
| contextDocument.createTextNode(carriedName))); |
| } |
| |
| return (result); |
| } |
| } |
| |
| private abstract class EncryptedTypeImpl { |
| private String id = null; |
| private String type = null; |
| private String mimeType = null; |
| private String encoding = null; |
| private EncryptionMethod encryptionMethod = null; |
| private KeyInfo keyInfo = null; |
| private CipherData cipherData = null; |
| private EncryptionProperties encryptionProperties = null; |
| |
| protected EncryptedTypeImpl(CipherData data) { |
| cipherData = data; |
| } |
| |
| public String getId() { |
| return (id); |
| } |
| |
| public void setId(String id) { |
| this.id = id; |
| } |
| |
| public String getType() { |
| return (type); |
| } |
| |
| public void setType(String type) { |
| URI tmpType = null; |
| try { |
| tmpType = new URI(type); |
| } catch (URI.MalformedURIException mfue) { |
| // complain |
| } |
| this.type = tmpType.toString(); |
| } |
| |
| public String getMimeType() { |
| return (mimeType); |
| } |
| |
| public void setMimeType(String type) { |
| mimeType = type; |
| } |
| |
| public String getEncoding() { |
| return (encoding); |
| } |
| |
| public void setEncoding(String encoding) { |
| URI tmpEncoding = null; |
| try { |
| tmpEncoding = new URI(encoding); |
| } catch (URI.MalformedURIException mfue) { |
| // complain |
| } |
| this.encoding = tmpEncoding.toString(); |
| } |
| |
| public EncryptionMethod getEncryptionMethod() { |
| return (encryptionMethod); |
| } |
| |
| public void setEncryptionMethod(EncryptionMethod method) { |
| encryptionMethod = method; |
| } |
| |
| public KeyInfo getKeyInfo() { |
| return (keyInfo); |
| } |
| |
| public void setKeyInfo(KeyInfo info) { |
| keyInfo = info; |
| } |
| |
| public CipherData getCipherData() { |
| return (cipherData); |
| } |
| |
| public EncryptionProperties getEncryptionProperties() { |
| return (encryptionProperties); |
| } |
| |
| public void setEncryptionProperties( |
| EncryptionProperties properties) { |
| encryptionProperties = properties; |
| } |
| } |
| |
| // <complexType name='EncryptionMethodType' mixed='true'> |
| // <sequence> |
| // <element name='KeySize' minOccurs='0' type='xenc:KeySizeType'/> |
| // <element name='OAEPparams' minOccurs='0' type='base64Binary'/> |
| // <any namespace='##other' minOccurs='0' maxOccurs='unbounded'/> |
| // </sequence> |
| // <attribute name='Algorithm' type='anyURI' use='required'/> |
| // </complexType> |
| private class EncryptionMethodImpl implements EncryptionMethod { |
| private String algorithm = null; |
| private int keySize = Integer.MIN_VALUE; |
| private byte[] oaepParams = null; |
| private List encryptionMethodInformation = null; |
| |
| public EncryptionMethodImpl(String algorithm) { |
| URI tmpAlgorithm = null; |
| try { |
| tmpAlgorithm = new URI(algorithm); |
| } catch (URI.MalformedURIException mfue) { |
| // complain |
| } |
| this.algorithm = tmpAlgorithm.toString(); |
| encryptionMethodInformation = new LinkedList(); |
| } |
| |
| public String getAlgorithm() { |
| return (algorithm); |
| } |
| |
| public int getKeySize() { |
| return (keySize); |
| } |
| |
| public void setKeySize(int size) { |
| keySize = size; |
| } |
| |
| public byte[] getOAEPparams() { |
| return (oaepParams); |
| } |
| |
| public void setOAEPparams(byte[] params) { |
| oaepParams = params; |
| } |
| |
| public Iterator getEncryptionMethodInformation() { |
| return (encryptionMethodInformation.iterator()); |
| } |
| |
| public void addEncryptionMethodInformation(Element info) { |
| encryptionMethodInformation.add(info); |
| } |
| |
| public void removeEncryptionMethodInformation(Element info) { |
| encryptionMethodInformation.remove(info); |
| } |
| |
| // <complexType name='EncryptionMethodType' mixed='true'> |
| // <sequence> |
| // <element name='KeySize' minOccurs='0' type='xenc:KeySizeType'/> |
| // <element name='OAEPparams' minOccurs='0' type='base64Binary'/> |
| // <any namespace='##other' minOccurs='0' maxOccurs='unbounded'/> |
| // </sequence> |
| // <attribute name='Algorithm' type='anyURI' use='required'/> |
| // </complexType> |
| Element toElement() { |
| Element result = ElementProxy.createElementForFamily( |
| contextDocument, EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_ENCRYPTIONMETHOD); |
| result.setAttributeNS(null, EncryptionConstants._ATT_ALGORITHM, |
| algorithm.toString()); |
| if (keySize > 0) { |
| result.appendChild( |
| ElementProxy.createElementForFamily(contextDocument, |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_KEYSIZE).appendChild( |
| contextDocument.createTextNode( |
| String.valueOf(keySize)))); |
| } |
| if (null != oaepParams) { |
| result.appendChild( |
| ElementProxy.createElementForFamily(contextDocument, |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_OAEPPARAMS).appendChild( |
| contextDocument.createTextNode( |
| new String(oaepParams)))); |
| } |
| if (!encryptionMethodInformation.isEmpty()) { |
| Iterator itr = encryptionMethodInformation.iterator(); |
| result.appendChild((Element) itr.next()); |
| } |
| |
| return (result); |
| } |
| } |
| |
| // <element name='EncryptionProperties' type='xenc:EncryptionPropertiesType'/> |
| // <complexType name='EncryptionPropertiesType'> |
| // <sequence> |
| // <element ref='xenc:EncryptionProperty' maxOccurs='unbounded'/> |
| // </sequence> |
| // <attribute name='Id' type='ID' use='optional'/> |
| // </complexType> |
| private class EncryptionPropertiesImpl implements EncryptionProperties { |
| private String id = null; |
| private List encryptionProperties = null; |
| |
| public EncryptionPropertiesImpl() { |
| encryptionProperties = new LinkedList(); |
| } |
| |
| public String getId() { |
| return (id); |
| } |
| |
| public void setId(String id) { |
| this.id = id; |
| } |
| |
| public Iterator getEncryptionProperties() { |
| return (encryptionProperties.iterator()); |
| } |
| |
| public void addEncryptionProperty(EncryptionProperty property) { |
| encryptionProperties.add(property); |
| } |
| |
| public void removeEncryptionProperty(EncryptionProperty property) { |
| encryptionProperties.remove(property); |
| } |
| |
| // <element name='EncryptionProperties' type='xenc:EncryptionPropertiesType'/> |
| // <complexType name='EncryptionPropertiesType'> |
| // <sequence> |
| // <element ref='xenc:EncryptionProperty' maxOccurs='unbounded'/> |
| // </sequence> |
| // <attribute name='Id' type='ID' use='optional'/> |
| // </complexType> |
| Element toElement() { |
| Element result = ElementProxy.createElementForFamily( |
| contextDocument, EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_ENCRYPTIONPROPERTIES); |
| if (null != id) { |
| result.setAttributeNS(null, EncryptionConstants._ATT_ID, id); |
| } |
| Iterator itr = getEncryptionProperties(); |
| while (itr.hasNext()) { |
| result.appendChild(((EncryptionPropertyImpl) |
| itr.next()).toElement()); |
| } |
| |
| return (result); |
| } |
| } |
| |
| // <element name='EncryptionProperty' type='xenc:EncryptionPropertyType'/> |
| // <complexType name='EncryptionPropertyType' mixed='true'> |
| // <choice maxOccurs='unbounded'> |
| // <any namespace='##other' processContents='lax'/> |
| // </choice> |
| // <attribute name='Target' type='anyURI' use='optional'/> |
| // <attribute name='Id' type='ID' use='optional'/> |
| // <anyAttribute namespace="http://www.w3.org/XML/1998/namespace"/> |
| // </complexType> |
| private class EncryptionPropertyImpl implements EncryptionProperty { |
| private String target = null; |
| private String id = null; |
| private String attributeName = null; |
| private String attributeValue = null; |
| private List encryptionInformation = null; |
| |
| public EncryptionPropertyImpl() { |
| encryptionInformation = new LinkedList(); |
| } |
| |
| public String getTarget() { |
| return (target); |
| } |
| |
| public void setTarget(String target) { |
| URI tmpTarget = null; |
| try { |
| tmpTarget = new URI(target); |
| } catch (URI.MalformedURIException mfue) { |
| // complain |
| } |
| this.target = tmpTarget.toString(); |
| } |
| |
| public String getId() { |
| return (id); |
| } |
| |
| public void setId(String id) { |
| this.id = id; |
| } |
| |
| public String getAttribute(String attribute) { |
| return (attributeValue); |
| } |
| |
| public void setAttribute(String attribute, String value) { |
| attributeName = attribute; |
| attributeValue = value; |
| } |
| |
| public Iterator getEncryptionInformation() { |
| return (encryptionInformation.iterator()); |
| } |
| |
| public void addEncryptionInformation(Element info) { |
| encryptionInformation.add(info); |
| } |
| |
| public void removeEncryptionInformation(Element info) { |
| encryptionInformation.remove(info); |
| } |
| |
| // <element name='EncryptionProperty' type='xenc:EncryptionPropertyType'/> |
| // <complexType name='EncryptionPropertyType' mixed='true'> |
| // <choice maxOccurs='unbounded'> |
| // <any namespace='##other' processContents='lax'/> |
| // </choice> |
| // <attribute name='Target' type='anyURI' use='optional'/> |
| // <attribute name='Id' type='ID' use='optional'/> |
| // <anyAttribute namespace="http://www.w3.org/XML/1998/namespace"/> |
| // </complexType> |
| Element toElement() { |
| Element result = ElementProxy.createElementForFamily( |
| contextDocument, EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_ENCRYPTIONPROPERTY); |
| if (null != target) { |
| result.setAttributeNS(null, EncryptionConstants._ATT_TARGET, |
| target.toString()); |
| } |
| if (null != id) { |
| result.setAttributeNS(null, EncryptionConstants._ATT_ID, |
| id); |
| } |
| // TODO: figure out the anyAttribyte stuff... |
| // TODO: figure out the any stuff... |
| |
| return (result); |
| } |
| } |
| |
| // <complexType name='TransformsType'> |
| // <sequence> |
| // <element ref='ds:Transform' maxOccurs='unbounded'/> |
| // </sequence> |
| // </complexType> |
| private class TransformsImpl implements Transforms { |
| private List transforms = null; |
| |
| public TransformsImpl() { |
| transforms = new LinkedList(); |
| } |
| |
| public Iterator getTransforms() { |
| return (transforms.iterator()); |
| } |
| |
| public void addTransform(Transform transform) { |
| transforms.add(transform); |
| } |
| |
| public void removeTransform(Transform transform) { |
| transforms.remove(transform); |
| } |
| |
| // <complexType name='TransformsType'> |
| // <sequence> |
| // <element ref='ds:Transform' maxOccurs='unbounded'/> |
| // </sequence> |
| // </complexType> |
| Element toElement() { |
| Element result = null; |
| |
| result = ElementProxy.createElementForFamily(contextDocument, |
| EncryptionConstants.EncryptionSpecNS, |
| EncryptionConstants._TAG_TRANSFORMS); |
| // TODO: figure out how to do this ... |
| |
| return (result); |
| } |
| } |
| } |
| } |