KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xml > internal > security > encryption > XMLCipher


1 /*
2  * Copyright 2003-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17 package com.sun.org.apache.xml.internal.security.encryption;
18
19
20 import java.io.ByteArrayOutputStream JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.StringReader JavaDoc;
23 import java.io.UnsupportedEncodingException JavaDoc;
24 import java.security.InvalidAlgorithmParameterException JavaDoc;
25 import java.security.InvalidKeyException JavaDoc;
26 import java.security.Key JavaDoc;
27 import java.security.NoSuchAlgorithmException JavaDoc;
28 import java.security.NoSuchProviderException JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.LinkedList JavaDoc;
31 import java.util.List JavaDoc;
32
33 import javax.crypto.BadPaddingException;
34 import javax.crypto.Cipher;
35 import javax.crypto.IllegalBlockSizeException;
36 import javax.crypto.NoSuchPaddingException;
37 import javax.crypto.spec.IvParameterSpec;
38 import javax.xml.parsers.DocumentBuilder JavaDoc;
39 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
40 import javax.xml.parsers.ParserConfigurationException JavaDoc;
41
42 import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper;
43 import com.sun.org.apache.xml.internal.security.algorithms.MessageDigestAlgorithm;
44 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
45 import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
46 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
47 import com.sun.org.apache.xml.internal.security.keys.KeyInfo;
48 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverException;
49 import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.EncryptedKeyResolver;
50 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException;
51 import com.sun.org.apache.xml.internal.security.transforms.InvalidTransformException;
52 import com.sun.org.apache.xml.internal.security.transforms.TransformationException;
53 import com.sun.org.apache.xml.internal.security.utils.Base64;
54 import com.sun.org.apache.xml.internal.security.utils.Constants;
55 import com.sun.org.apache.xml.internal.security.utils.ElementProxy;
56 import com.sun.org.apache.xml.internal.security.utils.EncryptionConstants;
57 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
58 import com.sun.org.apache.xml.internal.utils.URI;
59 import org.w3c.dom.Attr JavaDoc;
60 import org.w3c.dom.Document JavaDoc;
61 import org.w3c.dom.DocumentFragment JavaDoc;
62 import org.w3c.dom.Element JavaDoc;
63 import org.w3c.dom.NamedNodeMap JavaDoc;
64 import org.w3c.dom.Node JavaDoc;
65 import org.w3c.dom.NodeList JavaDoc;
66 import org.xml.sax.InputSource JavaDoc;
67 import org.xml.sax.SAXException JavaDoc;
68
69
70 /**
71  * <code>XMLCipher</code> encrypts and decrypts the contents of
72  * <code>Document</code>s, <code>Element</code>s and <code>Element</code>
73  * contents. It was designed to resemble <code>javax.crypto.Cipher</code> in
74  * order to facilitate understanding of its functioning.
75  *
76  * @author Axl Mattheus (Sun Microsystems)
77  * @author Christian Geuer-Pollmann
78  */

79 public class XMLCipher {
80
81     private static java.util.logging.Logger JavaDoc logger =
82         java.util.logging.Logger.getLogger(XMLCipher.class.getName());
83
84     //J-
85
/** Triple DES EDE (192 bit key) in CBC mode */
86     public static final String JavaDoc TRIPLEDES =
87         EncryptionConstants.ALGO_ID_BLOCKCIPHER_TRIPLEDES;
88     /** AES 128 Cipher */
89     public static final String JavaDoc AES_128 =
90         EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128;
91     /** AES 256 Cipher */
92     public static final String JavaDoc AES_256 =
93         EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256;
94     /** AES 192 Cipher */
95     public static final String JavaDoc AES_192 =
96         EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192;
97     /** RSA 1.5 Cipher */
98     public static final String JavaDoc RSA_v1dot5 =
99         EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15;
100     /** RSA OAEP Cipher */
101     public static final String JavaDoc RSA_OAEP =
102         EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP;
103     /** DIFFIE_HELLMAN Cipher */
104     public static final String JavaDoc DIFFIE_HELLMAN =
105         EncryptionConstants.ALGO_ID_KEYAGREEMENT_DH;
106     /** Triple DES EDE (192 bit key) in CBC mode KEYWRAP*/
107     public static final String JavaDoc TRIPLEDES_KeyWrap =
108         EncryptionConstants.ALGO_ID_KEYWRAP_TRIPLEDES;
109     /** AES 128 Cipher KeyWrap */
110     public static final String JavaDoc AES_128_KeyWrap =
111         EncryptionConstants.ALGO_ID_KEYWRAP_AES128;
112     /** AES 256 Cipher KeyWrap */
113     public static final String JavaDoc AES_256_KeyWrap =
114         EncryptionConstants.ALGO_ID_KEYWRAP_AES256;
115     /** AES 192 Cipher KeyWrap */
116     public static final String JavaDoc AES_192_KeyWrap =
117         EncryptionConstants.ALGO_ID_KEYWRAP_AES192;
118     /** SHA1 Cipher */
119     public static final String JavaDoc SHA1 =
120         Constants.ALGO_ID_DIGEST_SHA1;
121     /** SHA256 Cipher */
122     public static final String JavaDoc SHA256 =
123         MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA256;
124     /** SHA512 Cipher */
125     public static final String JavaDoc SHA512 =
126         MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA512;
127     /** RIPEMD Cipher */
128     public static final String JavaDoc RIPEMD_160 =
129         MessageDigestAlgorithm.ALGO_ID_DIGEST_RIPEMD160;
130     /** XML Signature NS */
131     public static final String JavaDoc XML_DSIG =
132         Constants.SignatureSpecNS;
133     /** N14C_XML */
134     public static final String JavaDoc N14C_XML =
135         Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS;
136     /** N14C_XML with comments*/
137     public static final String JavaDoc N14C_XML_WITH_COMMENTS =
138         Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS;
139     /** N14C_XML excluisve */
140     public static final String JavaDoc EXCL_XML_N14C =
141         Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
142     /** N14C_XML exclusive with commetns*/
143     public static final String JavaDoc EXCL_XML_N14C_WITH_COMMENTS =
144         Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS;
145     /** Base64 encoding */
146     public static final String JavaDoc BASE64_ENCODING =
147         com.sun.org.apache.xml.internal.security.transforms.Transforms.TRANSFORM_BASE64_DECODE;
148     //J+
149

150     /** ENCRYPT Mode */
151     public static final int ENCRYPT_MODE = Cipher.ENCRYPT_MODE;
152     /** DECRYPT Mode */
153     public static final int DECRYPT_MODE = Cipher.DECRYPT_MODE;
154     /** UNWRAP Mode */
155     public static final int UNWRAP_MODE = Cipher.UNWRAP_MODE;
156     /** WRAP Mode */
157     public static final int WRAP_MODE = Cipher.WRAP_MODE;
158     
159     private static final String JavaDoc ENC_ALGORITHMS = TRIPLEDES + "\n" +
160         AES_128 + "\n" + AES_256 + "\n" + AES_192 + "\n" + RSA_v1dot5 + "\n" +
161         RSA_OAEP + "\n" + TRIPLEDES_KeyWrap + "\n" + AES_128_KeyWrap + "\n" +
162         AES_256_KeyWrap + "\n" + AES_192_KeyWrap+ "\n";
163     
164     /** Cipher created during initialisation that is used for encryption */
165     private Cipher _contextCipher;
166     /** Mode that the XMLCipher object is operating in */
167     private int _cipherMode = Integer.MIN_VALUE;
168     /** URI of algorithm that is being used for cryptographic operation */
169     private String JavaDoc _algorithm = null;
170     /** Cryptographic provider requested by caller */
171     private String JavaDoc _requestedJCEProvider = null;
172     /** Holds c14n to serialize, if initialized then _always_ use this c14n to serialize */
173     private Canonicalizer _canon;
174     /** Used for creation of DOM nodes in WRAP and ENCRYPT modes */
175     private Document JavaDoc _contextDocument;
176     /** Instance of factory used to create XML Encryption objects */
177     private Factory JavaDoc _factory;
178     /** Internal serializer class for going to/from UTF-8 */
179     private Serializer _serializer;
180
181     /** Local copy of user's key */
182     private Key JavaDoc _key;
183     /** Local copy of the kek (used to decrypt EncryptedKeys during a
184      * DECRYPT_MODE operation */

185     private Key JavaDoc _kek;
186
187     // The EncryptedKey being built (part of a WRAP operation) or read
188
// (part of an UNWRAP operation)
189

190     private EncryptedKey _ek;
191
192     // The EncryptedData being built (part of a WRAP operation) or read
193
// (part of an UNWRAP operation)
194

195     private EncryptedData _ed;
196
197     /**
198      * Creates a new <code>XMLCipher</code>.
199      *
200      * @since 1.0.
201      */

202     private XMLCipher() {
203         if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Constructing XMLCipher...");
204
205         _factory = new Factory JavaDoc();
206         _serializer = new Serializer();
207
208     }
209
210     /**
211      * Checks to ensure that the supplied algorithm is valid.
212      *
213      * @param algorithm the algorithm to check.
214      * @return true if the algorithm is valid, otherwise false.
215      * @since 1.0.
216      */

217     private static boolean isValidEncryptionAlgorithm(String JavaDoc algorithm) {
218         boolean result = (
219             algorithm.equals(TRIPLEDES) ||
220             algorithm.equals(AES_128) ||
221             algorithm.equals(AES_256) ||
222             algorithm.equals(AES_192) ||
223             algorithm.equals(RSA_v1dot5) ||
224             algorithm.equals(RSA_OAEP) ||
225             algorithm.equals(TRIPLEDES_KeyWrap) ||
226             algorithm.equals(AES_128_KeyWrap) ||
227             algorithm.equals(AES_256_KeyWrap) ||
228             algorithm.equals(AES_192_KeyWrap)
229         );
230
231         return (result);
232     }
233
234     /**
235      * Returns an <code>XMLCipher</code> that implements the specified
236      * transformation and operates on the specified context document.
237      * <p>
238      * If the default provider package supplies an implementation of the
239      * requested transformation, an instance of Cipher containing that
240      * implementation is returned. If the transformation is not available in
241      * the default provider package, other provider packages are searched.
242      * <p>
243      * <b>NOTE<sub>1</sub>:</b> The transformation name does not follow the same
244      * pattern as that oulined in the Java Cryptography Extension Reference
245      * Guide but rather that specified by the XML Encryption Syntax and
246      * Processing document. The rational behind this is to make it easier for a
247      * novice at writing Java Encryption software to use the library.
248      * <p>
249      * <b>NOTE<sub>2</sub>:</b> <code>getInstance()</code> does not follow the
250      * same pattern regarding exceptional conditions as that used in
251      * <code>javax.crypto.Cipher</code>. Instead, it only throws an
252      * <code>XMLEncryptionException</code> which wraps an underlying exception.
253      * The stack trace from the exception should be self explanitory.
254      *
255      * @param transformation the name of the transformation, e.g.,
256      * <code>XMLCipher.TRIPLEDES</code> which is shorthand for
257      * &quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&quot;
258      * @throws XMLEncryptionException
259      * @return the XMLCipher
260      * @see javax.crypto.Cipher#getInstance(java.lang.String)
261      */

262     public static XMLCipher getInstance(String JavaDoc transformation) throws
263             XMLEncryptionException {
264         // sanity checks
265
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Getting XMLCipher...");
266         if (null == transformation)
267             logger.log(java.util.logging.Level.SEVERE, "Transformation unexpectedly null...");
268         if(!isValidEncryptionAlgorithm(transformation))
269             logger.log(java.util.logging.Level.WARNING, "Algorithm non-standard, expected one of " + ENC_ALGORITHMS);
270
271         XMLCipher instance = new XMLCipher();
272
273         instance._algorithm = transformation;
274         instance._key = null;
275         instance._kek = null;
276
277
278         /* Create a canonicaliser - used when serialising DOM to octets
279          * prior to encryption (and for the reverse) */

280
281         try {
282             instance._canon = Canonicalizer.getInstance
283                 (Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
284             
285         } catch (InvalidCanonicalizerException ice) {
286             throw new XMLEncryptionException("empty", ice);
287         }
288
289         String JavaDoc jceAlgorithm = JCEMapper.translateURItoJCEID(transformation);
290
291         try {
292             instance._contextCipher = Cipher.getInstance(jceAlgorithm);
293             if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "cihper.algoritm = " +
294                 instance._contextCipher.getAlgorithm());
295         } catch (NoSuchAlgorithmException JavaDoc nsae) {
296             throw new XMLEncryptionException("empty", nsae);
297         } catch (NoSuchPaddingException nspe) {
298             throw new XMLEncryptionException("empty", nspe);
299         }
300
301         return (instance);
302     }
303
304     public static XMLCipher getInstance(String JavaDoc transformation,Cipher cipher) throws
305             XMLEncryptionException {
306         // sanity checks
307
logger.log(java.util.logging.Level.FINE, "Getting XMLCipher...");
308         if (null == transformation)
309             logger.log(java.util.logging.Level.SEVERE, "Transformation unexpectedly null...");
310         if(!isValidEncryptionAlgorithm(transformation))
311             logger.log(java.util.logging.Level.WARNING, "Algorithm non-standard, expected one of " + ENC_ALGORITHMS);
312         
313         XMLCipher instance = new XMLCipher();
314         
315         instance._algorithm = transformation;
316         instance._key = null;
317         instance._kek = null;
318         
319         
320                 /* Create a canonicaliser - used when serialising DOM to octets
321                  * prior to encryption (and for the reverse) */

322         
323         try {
324             instance._canon = Canonicalizer.getInstance
325                     (Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
326             
327         } catch (InvalidCanonicalizerException ice) {
328             throw new XMLEncryptionException("empty", ice);
329         }
330         
331         String JavaDoc jceAlgorithm = JCEMapper.translateURItoJCEID(transformation);
332         
333         try {
334             instance._contextCipher = cipher;
335             //Cipher.getInstance(jceAlgorithm);
336
logger.log(java.util.logging.Level.FINE, "cihper.algoritm = " +
337                     instance._contextCipher.getAlgorithm());
338         }catch(Exception JavaDoc ex) {
339             throw new XMLEncryptionException("empty", ex);
340         }
341         
342         return (instance);
343     }
344     
345
346
347     /**
348      * Returns an <code>XMLCipher</code> that implements the specified
349      * transformation, operates on the specified context document and serializes
350      * the document with the specified canonicalization algorithm before it
351      * encrypts the document.
352      * <p>
353      *
354      * @param transformation the name of the transformation, e.g.,
355      * <code>XMLCipher.TRIPLEDES</code> which is
356      * shorthand for
357      * &quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&quot;
358      * @param canon the name of the c14n algorithm, if
359      * <code>null</code> use standard serializer
360      * @return
361      * @throws XMLEncryptionException
362      */

363
364     public static XMLCipher getInstance(String JavaDoc transformation, String JavaDoc canon)
365         throws XMLEncryptionException {
366         XMLCipher instance = XMLCipher.getInstance(transformation);
367
368         if (canon != null) {
369             try {
370                 instance._canon = Canonicalizer.getInstance(canon);
371             } catch (InvalidCanonicalizerException ice) {
372                 throw new XMLEncryptionException("empty", ice);
373             }
374         }
375
376         return instance;
377     }
378
379
380     /**
381      * Returns an <code>XMLCipher</code> that implements the specified
382      * transformation and operates on the specified context document.
383      *
384      * @param transformation the name of the transformation, e.g.,
385      * <code>XMLCipher.TRIPLEDES</code> which is shorthand for
386      * &quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&quot;
387      * @param provider the JCE provider that supplies the transformation
388      * @return the XMLCipher
389      * @throws XMLEncryptionException
390      */

391
392     public static XMLCipher getProviderInstance(String JavaDoc transformation, String JavaDoc provider)
393             throws XMLEncryptionException {
394         // sanity checks
395
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Getting XMLCipher...");
396         if (null == transformation)
397             logger.log(java.util.logging.Level.SEVERE, "Transformation unexpectedly null...");
398         if(null == provider)
399             logger.log(java.util.logging.Level.SEVERE, "Provider unexpectedly null..");
400         if("" == provider)
401             logger.log(java.util.logging.Level.SEVERE, "Provider's value unexpectedly not specified...");
402         if(!isValidEncryptionAlgorithm(transformation))
403             logger.log(java.util.logging.Level.WARNING, "Algorithm non-standard, expected one of " + ENC_ALGORITHMS);
404
405         XMLCipher instance = new XMLCipher();
406
407         instance._algorithm = transformation;
408         instance._requestedJCEProvider = provider;
409         instance._key = null;
410         instance._kek = null;
411
412         /* Create a canonicaliser - used when serialising DOM to octets
413          * prior to encryption (and for the reverse) */

414
415         try {
416             instance._canon = Canonicalizer.getInstance
417                 (Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
418         } catch (InvalidCanonicalizerException ice) {
419             throw new XMLEncryptionException("empty", ice);
420         }
421
422         try {
423             String JavaDoc jceAlgorithm =
424                 JCEMapper.translateURItoJCEID(transformation);
425
426             instance._contextCipher = Cipher.getInstance(jceAlgorithm, provider);
427
428             if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "cipher._algorithm = " +
429                 instance._contextCipher.getAlgorithm());
430             if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "provider.name = " + provider);
431         } catch (NoSuchAlgorithmException JavaDoc nsae) {
432             throw new XMLEncryptionException("empty", nsae);
433         } catch (NoSuchProviderException JavaDoc nspre) {
434             throw new XMLEncryptionException("empty", nspre);
435         } catch (NoSuchPaddingException nspe) {
436             throw new XMLEncryptionException("empty", nspe);
437         }
438
439         return (instance);
440     }
441     
442     /**
443      * Returns an <code>XMLCipher</code> that implements the specified
444      * transformation, operates on the specified context document and serializes
445      * the document with the specified canonicalization algorithm before it
446      * encrypts the document.
447      * <p>
448      *
449      * @param transformation the name of the transformation, e.g.,
450      * <code>XMLCipher.TRIPLEDES</code> which is
451      * shorthand for
452      * &quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&quot;
453      * @param provider the JCE provider that supplies the transformation
454      * @param canon the name of the c14n algorithm, if
455      * <code>null</code> use standard serializer
456      * @return
457      * @throws XMLEncryptionException
458      */

459     public static XMLCipher getProviderInstance(
460         String JavaDoc transformation,
461         String JavaDoc provider,
462         String JavaDoc canon)
463         throws XMLEncryptionException {
464
465         XMLCipher instance = XMLCipher.getProviderInstance(transformation, provider);
466         if (canon != null) {
467             try {
468                 instance._canon = Canonicalizer.getInstance(canon);
469             } catch (InvalidCanonicalizerException ice) {
470                 throw new XMLEncryptionException("empty", ice);
471             }
472         }
473         return instance;
474     }
475
476     /**
477      * Returns an <code>XMLCipher</code> that implements no specific
478      * transformation, and can therefore only be used for decrypt or
479      * unwrap operations where the encryption method is defined in the
480      * <code>EncryptionMethod</code> element.
481      *
482      * @return The XMLCipher
483      * @throws XMLEncryptionException
484      */

485
486     public static XMLCipher getInstance()
487             throws XMLEncryptionException {
488         // sanity checks
489
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Getting XMLCipher for no transformation...");
490
491         XMLCipher instance = new XMLCipher();
492
493         instance._algorithm = null;
494         instance._requestedJCEProvider = null;
495         instance._key = null;
496         instance._kek = null;
497         instance._contextCipher = null;
498
499         /* Create a canonicaliser - used when serialising DOM to octets
500          * prior to encryption (and for the reverse) */

501
502         try {
503             instance._canon = Canonicalizer.getInstance
504                 (Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
505         } catch (InvalidCanonicalizerException ice) {
506             throw new XMLEncryptionException("empty", ice);
507         }
508
509         return (instance);
510     }
511
512     /**
513      * Returns an <code>XMLCipher</code> that implements no specific
514      * transformation, and can therefore only be used for decrypt or
515      * unwrap operations where the encryption method is defined in the
516      * <code>EncryptionMethod</code> element.
517      *
518      * Allows the caller to specify a provider that will be used for
519      * cryptographic operations.
520      *
521      * @param provider the JCE provider that supplies the cryptographic
522      * needs.
523      * @return the XMLCipher
524      * @throws XMLEncryptionException
525      */

526
527     public static XMLCipher getProviderInstance(String JavaDoc provider)
528             throws XMLEncryptionException {
529         // sanity checks
530

531         if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Getting XMLCipher, provider but no transformation");
532         if(null == provider)
533             logger.log(java.util.logging.Level.SEVERE, "Provider unexpectedly null..");
534         if("" == provider)
535             logger.log(java.util.logging.Level.SEVERE, "Provider's value unexpectedly not specified...");
536
537         XMLCipher instance = new XMLCipher();
538
539         instance._algorithm = null;
540         instance._requestedJCEProvider = provider;
541         instance._key = null;
542         instance._kek = null;
543         instance._contextCipher = null;
544
545         try {
546             instance._canon = Canonicalizer.getInstance
547                 (Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
548         } catch (InvalidCanonicalizerException ice) {
549             throw new XMLEncryptionException("empty", ice);
550         }
551
552         return (instance);
553     }
554
555     /**
556      * Initializes this cipher with a key.
557      * <p>
558      * The cipher is initialized for one of the following four operations:
559      * encryption, decryption, key wrapping or key unwrapping, depending on the
560      * value of opmode.
561      *
562      * For WRAP and ENCRYPT modes, this also initialises the internal
563      * EncryptedKey or EncryptedData (with a CipherValue)
564      * structure that will be used during the ensuing operations. This
565      * can be obtained (in order to modify KeyInfo elements etc. prior to
566      * finalising the encryption) by calling
567      * {@link #getEncryptedData} or {@link #getEncryptedKey}.
568      *
569      * @param opmode the operation mode of this cipher (this is one of the
570      * following: ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE or UNWRAP_MODE)
571      * @param key
572      * @see javax.crypto.Cipher#init(int, java.security.Key)
573      * @throws XMLEncryptionException
574      */

575     public void init(int opmode, Key JavaDoc key) throws XMLEncryptionException {
576         // sanity checks
577
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Initializing XMLCipher...");
578
579         _ek = null;
580         _ed = null;
581
582         switch (opmode) {
583
584         case ENCRYPT_MODE :
585             if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "opmode = ENCRYPT_MODE");
586             _ed = createEncryptedData(CipherData.VALUE_TYPE, "NO VALUE YET");
587             break;
588         case DECRYPT_MODE :
589             if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "opmode = DECRYPT_MODE");
590             break;
591         case WRAP_MODE :
592             if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "opmode = WRAP_MODE");
593             _ek = createEncryptedKey(CipherData.VALUE_TYPE, "NO VALUE YET");
594             break;
595         case UNWRAP_MODE :
596             if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "opmode = UNWRAP_MODE");
597             break;
598         default :
599             logger.log(java.util.logging.Level.SEVERE, "Mode unexpectedly invalid");
600             throw new XMLEncryptionException("Invalid mode in init");
601         }
602
603         _cipherMode = opmode;
604         _key = key;
605
606     }
607
608     /**
609      * Get the EncryptedData being build
610      *
611      * Returns the EncryptedData being built during an ENCRYPT operation.
612      * This can then be used by applications to add KeyInfo elements and
613      * set other parameters.
614      *
615      * @return The EncryptedData being built
616      */

617
618     public EncryptedData getEncryptedData() {
619
620         // Sanity checks
621
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Returning EncryptedData");
622         return _ed;
623
624     }
625
626     /**
627      * Get the EncryptedData being build
628      *
629      * Returns the EncryptedData being built during an ENCRYPT operation.
630      * This can then be used by applications to add KeyInfo elements and
631      * set other parameters.
632      *
633      * @return The EncryptedData being built
634      */

635
636     public EncryptedKey getEncryptedKey() {
637
638         // Sanity checks
639
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Returning EncryptedKey");
640         return _ek;
641     }
642
643     /**
644      * Set a Key Encryption Key.
645      * <p>
646      * The Key Encryption Key (KEK) is used for encrypting/decrypting
647      * EncryptedKey elements. By setting this separately, the XMLCipher
648      * class can know whether a key applies to the data part or wrapped key
649      * part of an encrypted object.
650      *
651      * @param kek The key to use for de/encrypting key data
652      */

653
654     public void setKEK(Key JavaDoc kek) {
655
656         _kek = kek;
657
658     }
659
660     /**
661      * Martial an EncryptedData
662      *
663      * Takes an EncryptedData object and returns a DOM Element that
664      * represents the appropriate <code>EncryptedData</code>
665      * <p>
666      * <b>Note:</b> This should only be used in cases where the context
667      * document has been passed in via a call to doFinal.
668      *
669      * @param encryptedData EncryptedData object to martial
670      * @return the DOM <code>Element</code> representing the passed in
671      * object
672      */

673
674     public Element JavaDoc martial(EncryptedData encryptedData) {
675
676         return (_factory.toElement (encryptedData));
677
678     }
679
680     /**
681      * Martial an EncryptedKey
682      *
683      * Takes an EncryptedKey object and returns a DOM Element that
684      * represents the appropriate <code>EncryptedKey</code>
685      *
686      * <p>
687      * <b>Note:</b> This should only be used in cases where the context
688      * document has been passed in via a call to doFinal.
689      *
690      * @param encryptedKey EncryptedKey object to martial
691      * @return the DOM <code>Element</code> representing the passed in
692      * object */

693
694     public Element JavaDoc martial(EncryptedKey encryptedKey) {
695
696         return (_factory.toElement (encryptedKey));
697
698     }
699
700     /**
701      * Martial an EncryptedData
702      *
703      * Takes an EncryptedData object and returns a DOM Element that
704      * represents the appropriate <code>EncryptedData</code>
705      *
706      * @param context The document that will own the returned nodes
707      * @param encryptedData EncryptedData object to martial
708      * @return the DOM <code>Element</code> representing the passed in
709      * object */

710
711     public Element JavaDoc martial(Document JavaDoc context, EncryptedData encryptedData) {
712
713         _contextDocument = context;
714         return (_factory.toElement (encryptedData));
715
716     }
717
718     /**
719      * Martial an EncryptedKey
720      *
721      * Takes an EncryptedKey object and returns a DOM Element that
722      * represents the appropriate <code>EncryptedKey</code>
723      *
724      * @param context The document that will own the created nodes
725      * @param encryptedKey EncryptedKey object to martial
726      * @return the DOM <code>Element</code> representing the passed in
727      * object */

728
729     public Element JavaDoc martial(Document JavaDoc context, EncryptedKey encryptedKey) {
730
731         _contextDocument = context;
732         return (_factory.toElement (encryptedKey));
733
734     }
735
736     /**
737      * Encrypts an <code>Element</code> and replaces it with its encrypted
738      * counterpart in the context <code>Document</code>, that is, the
739      * <code>Document</code> specified when one calls
740      * {@link #getInstance(String) getInstance}.
741      *
742      * @param element the <code>Element</code> to encrypt.
743      * @return the context <code>Document</code> with the encrypted
744      * <code>Element</code> having replaced the source <code>Element</code>.
745      * @throws Exception
746      */

747
748     private Document JavaDoc encryptElement(Element JavaDoc element) throws Exception JavaDoc{
749         if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypting element...");
750         if(null == element)
751             logger.log(java.util.logging.Level.SEVERE, "Element unexpectedly null...");
752         if(_cipherMode != ENCRYPT_MODE)
753             if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE...");
754
755         if (_algorithm == null) {
756             throw new XMLEncryptionException("XMLCipher instance without transformation specified");
757         }
758         encryptData(_contextDocument, element, false);
759
760         Element JavaDoc encryptedElement = _factory.toElement(_ed);
761
762         Node JavaDoc sourceParent = element.getParentNode();
763         sourceParent.replaceChild(encryptedElement, element);
764
765         return (_contextDocument);
766     }
767
768     /**
769      * Encrypts a <code>NodeList</code> (the contents of an
770      * <code>Element</code>) and replaces its parent <code>Element</code>'s
771      * content with this the resulting <code>EncryptedType</code> within the
772      * context <code>Document</code>, that is, the <code>Document</code>
773      * specified when one calls
774      * {@link #getInstance(String) getInstance}.
775      *
776      * @param element the <code>NodeList</code> to encrypt.
777      * @return the context <code>Document</code> with the encrypted
778      * <code>NodeList</code> having replaced the content of the source
779      * <code>Element</code>.
780      * @throws Exception
781      */

782     private Document JavaDoc encryptElementContent(Element JavaDoc element) throws
783             /* XMLEncryption */Exception JavaDoc {
784         if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypting element content...");
785         if(null == element)
786             logger.log(java.util.logging.Level.SEVERE, "Element unexpectedly null...");
787         if(_cipherMode != ENCRYPT_MODE)
788             if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE...");
789
790         if (_algorithm == null) {
791             throw new XMLEncryptionException("XMLCipher instance without transformation specified");
792         }
793         encryptData(_contextDocument, element, true);
794
795         Element JavaDoc encryptedElement = _factory.toElement(_ed);
796
797         removeContent(element);
798         element.appendChild(encryptedElement);
799
800         return (_contextDocument);
801     }
802
803     /**
804      * Process a DOM <code>Document</code> node. The processing depends on the
805      * initialization parameters of {@link #init(int, Key) init()}.
806      *
807      * @param context the context <code>Document</code>.
808      * @param source the <code>Document</code> to be encrypted or decrypted.
809      * @return the processed <code>Document</code>.
810      * @throws Exception to indicate any exceptional conditions.
811      */

812     public Document JavaDoc doFinal(Document JavaDoc context, Document JavaDoc source) throws
813             /* XMLEncryption */Exception JavaDoc {
814         if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Processing source document...");
815         if(null == context)
816             logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
817         if(null == source)
818             logger.log(java.util.logging.Level.SEVERE, "Source document unexpectedly null...");
819
820         _contextDocument = context;
821
822         Document JavaDoc result = null;
823
824         switch (_cipherMode) {
825         case DECRYPT_MODE:
826             result = decryptElement(source.getDocumentElement());
827             break;
828         case ENCRYPT_MODE:
829             result = encryptElement(source.getDocumentElement());
830             break;
831         case UNWRAP_MODE:
832             break;
833         case WRAP_MODE:
834             break;
835         default:
836             throw new XMLEncryptionException(
837                 "empty", new IllegalStateException JavaDoc());
838         }
839
840         return (result);
841     }
842
843     /**
844      * Process a DOM <code>Element</code> node. The processing depends on the
845      * initialization parameters of {@link #init(int, Key) init()}.
846      *
847      * @param context the context <code>Document</code>.
848      * @param element the <code>Element</code> to be encrypted.
849      * @return the processed <code>Document</code>.
850      * @throws Exception to indicate any exceptional conditions.
851      */

852     public Document JavaDoc doFinal(Document JavaDoc context, Element JavaDoc element) throws
853             /* XMLEncryption */Exception JavaDoc {
854         if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Processing source element...");
855         if(null == context)
856             logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
857         if(null == element)
858             logger.log(java.util.logging.Level.SEVERE, "Source element unexpectedly null...");
859
860         _contextDocument = context;
861
862         Document JavaDoc result = null;
863
864         switch (_cipherMode) {
865         case DECRYPT_MODE:
866             result = decryptElement(element);
867             break;
868         case ENCRYPT_MODE:
869             result = encryptElement(element);
870             break;
871         case UNWRAP_MODE:
872             break;
873         case WRAP_MODE:
874             break;
875         default:
876             throw new XMLEncryptionException(
877                 "empty", new IllegalStateException JavaDoc());
878         }
879
880         return (result);
881     }
882
883     /**
884      * Process the contents of a DOM <code>Element</code> node. The processing
885      * depends on the initialization parameters of
886      * {@link #init(int, Key) init()}.
887      *
888      * @param context the context <code>Document</code>.
889      * @param element the <code>Element</code> which contents is to be
890      * encrypted.
891      * @param content
892      * @return the processed <code>Document</code>.
893      * @throws Exception to indicate any exceptional conditions.
894      */

895     public Document JavaDoc doFinal(Document JavaDoc context, Element JavaDoc element, boolean content)
896             throws /* XMLEncryption*/ Exception JavaDoc {
897         if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Processing source element...");
898         if(null == context)
899             logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
900         if(null == element)
901             logger.log(java.util.logging.Level.SEVERE, "Source element unexpectedly null...");
902
903         _contextDocument = context;
904
905         Document JavaDoc result = null;
906
907         switch (_cipherMode) {
908         case DECRYPT_MODE:
909             if (content) {
910                 result = decryptElementContent(element);
911             } else {
912                 result = decryptElement(element);
913             }
914             break;
915         case ENCRYPT_MODE:
916             if (content) {
917                 result = encryptElementContent(element);
918             } else {
919                 result = encryptElement(element);
920             }
921             break;
922         case UNWRAP_MODE:
923             break;
924         case WRAP_MODE:
925             break;
926         default:
927             throw new XMLEncryptionException(
928                 "empty", new IllegalStateException JavaDoc());
929         }
930
931         return (result);
932     }
933
934     /**
935      * Returns an <code>EncryptedData</code> interface. Use this operation if
936      * you want to have full control over the contents of the
937      * <code>EncryptedData</code> structure.
938      *
939      * this does not change the source document in any way.
940      *
941      * @param context the context <code>Document</code>.
942      * @param element the <code>Element</code> that will be encrypted.
943      * @return the <code>EncryptedData</code>
944      * @throws Exception
945      */

946     public EncryptedData encryptData(Document JavaDoc context, Element JavaDoc element) throws
947             /* XMLEncryption */Exception JavaDoc {
948     return encryptData(context, element, false);
949     }
950
951     /**
952      * Returns an <code>EncryptedData</code> interface. Use this operation if
953      * you want to have full control over the contents of the
954      * <code>EncryptedData</code> structure.
955      *
956      * this does not change the source document in any way.
957      *
958      * @param context the context <code>Document</code>.
959      * @param element the <code>Element</code> that will be encrypted.
960      * @param contentMode <code>true</code> to encrypt element's content only,
961      * <code>false</code> otherwise
962      * @return the <code>EncryptedData</code>
963      * @throws Exception
964      */

965     public EncryptedData encryptData(Document JavaDoc context, Element JavaDoc element, boolean contentMode) throws
966             /* XMLEncryption */ Exception JavaDoc {
967         if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypting element...");
968         if (null == context)
969             logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
970         if (null == element)
971             logger.log(java.util.logging.Level.SEVERE, "Element unexpectedly null...");
972         if (_cipherMode != ENCRYPT_MODE)
973             if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE...");
974
975         _contextDocument = context;
976
977         if (_algorithm == null) {
978             throw new XMLEncryptionException("XMLCipher instance without transformation specified");
979         }
980
981         String JavaDoc serializedOctets = null;
982         if (contentMode) {
983             NodeList JavaDoc children = element.getChildNodes();
984             if ((null != children)) {
985                 serializedOctets = _serializer.serialize(children);
986             } else {
987                 Object JavaDoc exArgs[] = { "Element has no content." };
988                 throw new XMLEncryptionException("empty", exArgs);
989             }
990         } else {
991             serializedOctets = _serializer.serialize(element);
992         }
993         if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Serialized octets:\n" + serializedOctets);
994
995         byte[] encryptedBytes = null;
996
997         // Now create the working cipher if none was created already
998
Cipher c;
999         if (_contextCipher == null) {
1000            String JavaDoc jceAlgorithm =
1001                JCEMapper.translateURItoJCEID(_algorithm);
1002
1003            if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "alg = " + jceAlgorithm);
1004
1005            try {
1006                            if (_requestedJCEProvider == null)
1007                c = Cipher.getInstance(jceAlgorithm);
1008                            else
1009                                c = Cipher.getInstance(jceAlgorithm, _requestedJCEProvider);
1010            } catch (NoSuchAlgorithmException JavaDoc nsae) {
1011                throw new XMLEncryptionException("empty", nsae);
1012            } catch (NoSuchProviderException JavaDoc nspre) {
1013                throw new XMLEncryptionException("empty", nspre);
1014            } catch (NoSuchPaddingException nspae) {
1015                throw new XMLEncryptionException("empty", nspae);
1016            }
1017        }
1018        else {
1019            c = _contextCipher;
1020        }
1021        // Now perform the encryption
1022

1023        try {
1024            // Should internally generate an IV
1025
// todo - allow user to set an IV
1026
c.init(_cipherMode, _key);
1027        } catch (InvalidKeyException JavaDoc ike) {
1028            throw new XMLEncryptionException("empty", ike);
1029        }
1030
1031        try {
1032            encryptedBytes =
1033                c.doFinal(serializedOctets.getBytes("UTF-8"));
1034
1035            if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Expected cipher.outputSize = " +
1036                Integer.toString(c.getOutputSize(
1037                    serializedOctets.getBytes().length)));
1038            if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Actual cipher.outputSize = " +
1039                Integer.toString(encryptedBytes.length));
1040        } catch (IllegalStateException JavaDoc ise) {
1041            throw new XMLEncryptionException("empty", ise);
1042        } catch (IllegalBlockSizeException ibse) {
1043            throw new XMLEncryptionException("empty", ibse);
1044        } catch (BadPaddingException bpe) {
1045            throw new XMLEncryptionException("empty", bpe);
1046        } catch (UnsupportedEncodingException JavaDoc uee) {
1047            throw new XMLEncryptionException("empty", uee);
1048        }
1049
1050        // Now build up to a properly XML Encryption encoded octet stream
1051
// IvParameterSpec iv;
1052

1053        byte[] iv = c.getIV();
1054        byte[] finalEncryptedBytes =
1055            new byte[iv.length + encryptedBytes.length];
1056        System.arraycopy(iv, 0, finalEncryptedBytes, 0,
1057                         iv.length);
1058        System.arraycopy(encryptedBytes, 0, finalEncryptedBytes,
1059                         iv.length,
1060                         encryptedBytes.length);
1061
1062        String JavaDoc base64EncodedEncryptedOctets = Base64.encode(finalEncryptedBytes);
1063
1064        if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypted octets:\n" + base64EncodedEncryptedOctets);
1065        if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypted octets length = " +
1066            base64EncodedEncryptedOctets.length());
1067
1068        try {
1069            CipherData cd = _ed.getCipherData();
1070            CipherValue cv = cd.getCipherValue();
1071            // cv.setValue(base64EncodedEncryptedOctets.getBytes());
1072
cv.setValue(base64EncodedEncryptedOctets);
1073
1074            if (contentMode) {
1075                _ed.setType(
1076                    new URI(EncryptionConstants.TYPE_CONTENT).toString());
1077            } else {
1078                _ed.setType(
1079                    new URI(EncryptionConstants.TYPE_ELEMENT).toString());
1080            }
1081            EncryptionMethod method =
1082                _factory.newEncryptionMethod(new URI(_algorithm).toString());
1083            _ed.setEncryptionMethod(method);
1084        } catch (URI.MalformedURIException mfue) {
1085            throw new XMLEncryptionException("empty", mfue);
1086        }
1087        return (_ed);
1088    }
1089
1090
1091   
1092    public EncryptedData encryptData(Document JavaDoc context, byte [] serializedOctets, boolean contentMode) throws
1093            /* XMLEncryption */ Exception JavaDoc {
1094        logger.log(java.util.logging.Level.FINE, "Encrypting element...");
1095        if (null == context)
1096            logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
1097        if (null == serializedOctets)
1098            logger.log(java.util.logging.Level.SEVERE, "Canonicalized Data is unexpectedly null...");
1099        if (_cipherMode != ENCRYPT_MODE)
1100            logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE...");
1101        
1102        _contextDocument = context;
1103        
1104        if (_algorithm == null) {
1105            throw new XMLEncryptionException("XMLCipher instance without transformation specified");
1106        }
1107        
1108       
1109        logger.log(java.util.logging.Level.FINE, "Serialized octets:\n" + serializedOctets);
1110        
1111        byte[] encryptedBytes = null;
1112        
1113        // Now create the working cipher if none was created already
1114
Cipher c;
1115        if (_contextCipher == null) {
1116            String JavaDoc jceAlgorithm =
1117                    JCEMapper.translateURItoJCEID(_algorithm);
1118            
1119            logger.log(java.util.logging.Level.FINE, "alg = " + jceAlgorithm);
1120            
1121            try {
1122                if (_requestedJCEProvider == null)
1123                    c = Cipher.getInstance(jceAlgorithm);
1124                else
1125                    c = Cipher.getInstance(jceAlgorithm, _requestedJCEProvider);
1126            } catch (NoSuchAlgorithmException JavaDoc nsae) {
1127                throw new XMLEncryptionException("empty", nsae);
1128            } catch (NoSuchProviderException JavaDoc nspre) {
1129                throw new XMLEncryptionException("empty", nspre);
1130            } catch (NoSuchPaddingException nspae) {
1131                throw new XMLEncryptionException("empty", nspae);
1132            }
1133        } else {
1134            c = _contextCipher;
1135        }
1136        // Now perform the encryption
1137

1138        try {
1139            // Should internally generate an IV
1140
// todo - allow user to set an IV
1141
c.init(_cipherMode, _key);
1142        } catch (InvalidKeyException JavaDoc ike) {
1143            throw new XMLEncryptionException("empty", ike);
1144        }
1145        
1146        try {
1147            encryptedBytes =
1148                    c.doFinal(serializedOctets);
1149            
1150            logger.log(java.util.logging.Level.FINE, "Expected cipher.outputSize = " +
1151                    Integer.toString(c.getOutputSize(
1152                    serializedOctets.length)));
1153            logger.log(java.util.logging.Level.FINE, "Actual cipher.outputSize = " +
1154                    Integer.toString(encryptedBytes.length));
1155        } catch (IllegalStateException JavaDoc ise) {
1156            throw new XMLEncryptionException("empty", ise);
1157        } catch (IllegalBlockSizeException ibse) {
1158            throw new XMLEncryptionException("empty", ibse);
1159        } catch (BadPaddingException bpe) {
1160            throw new XMLEncryptionException("empty", bpe);
1161        } catch (Exception JavaDoc uee) {
1162            throw new XMLEncryptionException("empty", uee);
1163        }
1164        
1165        // Now build up to a properly XML Encryption encoded octet stream
1166
// IvParameterSpec iv;
1167

1168        byte[] iv = c.getIV();
1169        byte[] finalEncryptedBytes =
1170                new byte[iv.length + encryptedBytes.length];
1171        System.arraycopy(iv, 0, finalEncryptedBytes, 0,
1172                iv.length);
1173        System.arraycopy(encryptedBytes, 0, finalEncryptedBytes,
1174                iv.length,
1175                encryptedBytes.length);
1176        
1177        String JavaDoc base64EncodedEncryptedOctets = Base64.encode(finalEncryptedBytes);
1178        
1179        logger.log(java.util.logging.Level.FINE, "Encrypted octets:\n" + base64EncodedEncryptedOctets);
1180        logger.log(java.util.logging.Level.FINE, "Encrypted octets length = " +
1181                base64EncodedEncryptedOctets.length());
1182        
1183        try {
1184            CipherData cd = _ed.getCipherData();
1185            CipherValue cv = cd.getCipherValue();
1186            // cv.setValue(base64EncodedEncryptedOctets.getBytes());
1187
cv.setValue(base64EncodedEncryptedOctets);
1188            
1189            if (contentMode) {
1190                _ed.setType(
1191                        new URI(EncryptionConstants.TYPE_CONTENT).toString());
1192            } else {
1193                _ed.setType(
1194                        new URI(EncryptionConstants.TYPE_ELEMENT).toString());
1195            }
1196            EncryptionMethod method =
1197                    _factory.newEncryptionMethod(new URI(_algorithm).toString());
1198            _ed.setEncryptionMethod(method);
1199        } catch (URI.MalformedURIException mfue) {
1200            throw new XMLEncryptionException("empty", mfue);
1201        }
1202        return (_ed);
1203    }
1204
1205
1206    /**
1207     * Returns an <code>EncryptedData</code> interface. Use this operation if
1208     * you want to load an <code>EncryptedData</code> structure from a DOM
1209     * structure and manipulate the contents
1210     *
1211     * @param context the context <code>Document</code>.
1212     * @param element the <code>Element</code> that will be loaded
1213     * @throws XMLEncryptionException
1214     * @return
1215     */

1216    public EncryptedData loadEncryptedData(Document JavaDoc context, Element JavaDoc element)
1217        throws XMLEncryptionException {
1218        if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Loading encrypted element...");
1219        if(null == context)
1220            logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
1221        if(null == element)
1222            logger.log(java.util.logging.Level.SEVERE, "Element unexpectedly null...");
1223        if(_cipherMode != DECRYPT_MODE)
1224            logger.log(java.util.logging.Level.SEVERE, "XMLCipher unexpectedly not in DECRYPT_MODE...");
1225
1226        _contextDocument = context;
1227        _ed = _factory.newEncryptedData(element);
1228
1229        return (_ed);
1230    }
1231
1232    /**
1233     * Returns an <code>EncryptedKey</code> interface. Use this operation if
1234     * you want to load an <code>EncryptedKey</code> structure from a DOM
1235     * structure and manipulate the contents.
1236     *
1237     * @param context the context <code>Document</code>.
1238     * @param element the <code>Element</code> that will be loaded
1239     * @return
1240     * @throws XMLEncryptionException
1241     */

1242
1243    public EncryptedKey loadEncryptedKey(Document JavaDoc context, Element JavaDoc element)
1244        throws XMLEncryptionException {
1245        if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Loading encrypted key...");
1246        if(null == context)
1247            logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
1248        if(null == element)
1249            logger.log(java.util.logging.Level.SEVERE, "Element unexpectedly null...");
1250        if(_cipherMode != UNWRAP_MODE && _cipherMode != DECRYPT_MODE)
1251            if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in UNWRAP_MODE or DECRYPT_MODE...");
1252
1253        _contextDocument = context;
1254        _ek = _factory.newEncryptedKey(element);
1255        return (_ek);
1256    }
1257
1258    /**
1259     * Returns an <code>EncryptedKey</code> interface. Use this operation if
1260     * you want to load an <code>EncryptedKey</code> structure from a DOM
1261     * structure and manipulate the contents.
1262     *
1263     * Assumes that the context document is the document that owns the element
1264     *
1265     * @param element the <code>Element</code> that will be loaded
1266     * @return
1267     * @throws XMLEncryptionException
1268     */

1269
1270    public EncryptedKey loadEncryptedKey(Element JavaDoc element)
1271        throws XMLEncryptionException {
1272
1273        return (loadEncryptedKey(element.getOwnerDocument(), element));
1274    }
1275
1276    /**
1277     * Encrypts a key to an EncryptedKey structure
1278     *
1279     * @param doc the Context document that will be used to general DOM
1280     * @param key Key to encrypt (will use previously set KEK to
1281     * perform encryption
1282     * @return
1283     * @throws XMLEncryptionException
1284     */

1285
1286    public EncryptedKey encryptKey(Document JavaDoc doc, Key JavaDoc key) throws
1287            XMLEncryptionException {
1288
1289        if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypting key ...");
1290
1291        if(null == key)
1292            logger.log(java.util.logging.Level.SEVERE, "Key unexpectedly null...");
1293        if(_cipherMode != WRAP_MODE)
1294            if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in WRAP_MODE...");
1295
1296        if (_algorithm == null) {
1297
1298            throw new XMLEncryptionException("XMLCipher instance without transformation specified");
1299        }
1300
1301        _contextDocument = doc;
1302
1303        byte[] encryptedBytes = null;
1304        Cipher c;
1305
1306        if (_contextCipher == null) {
1307            // Now create the working cipher
1308

1309            String JavaDoc jceAlgorithm =
1310                JCEMapper.translateURItoJCEID(_algorithm);
1311
1312            if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "alg = " + jceAlgorithm);
1313
1314            try {
1315                if (_requestedJCEProvider == null)
1316                c = Cipher.getInstance(jceAlgorithm);
1317                            else
1318                                c = Cipher.getInstance(jceAlgorithm, _requestedJCEProvider);
1319            } catch (NoSuchAlgorithmException JavaDoc nsae) {
1320                throw new XMLEncryptionException("empty", nsae);
1321            } catch (NoSuchProviderException JavaDoc nspre) {
1322                throw new XMLEncryptionException("empty", nspre);
1323            } catch (NoSuchPaddingException nspae) {
1324                throw new XMLEncryptionException("empty", nspae);
1325            }
1326        } else {
1327            c = _contextCipher;
1328        }
1329        // Now perform the encryption
1330

1331        try {
1332            // Should internally generate an IV
1333
// todo - allow user to set an IV
1334
c.init(Cipher.WRAP_MODE, _key);
1335            encryptedBytes = c.wrap(key);
1336        } catch (InvalidKeyException JavaDoc ike) {
1337            throw new XMLEncryptionException("empty", ike);
1338        } catch (IllegalBlockSizeException ibse) {
1339            throw new XMLEncryptionException("empty", ibse);
1340        }
1341
1342        String JavaDoc base64EncodedEncryptedOctets = Base64.encode(encryptedBytes);
1343
1344        if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypted key octets:\n" + base64EncodedEncryptedOctets);
1345        if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypted key octets length = " +
1346            base64EncodedEncryptedOctets.length());
1347
1348        CipherValue cv = _ek.getCipherData().getCipherValue();
1349        cv.setValue(base64EncodedEncryptedOctets);
1350
1351        try {
1352            EncryptionMethod method = _factory.newEncryptionMethod(
1353                new URI(_algorithm).toString());
1354            _ek.setEncryptionMethod(method);
1355        } catch (URI.MalformedURIException mfue) {
1356            throw new XMLEncryptionException("empty", mfue);
1357        }
1358        return _ek;
1359        
1360    }
1361
1362    /**
1363     * Decrypt a key from a passed in EncryptedKey structure
1364     *
1365     * @param encryptedKey Previously loaded EncryptedKey that needs
1366     * to be decrypted.
1367     * @param algorithm Algorithm for the decryption
1368     * @return a key corresponding to the give type
1369     * @throws XMLEncryptionException
1370     */

1371
1372    public Key JavaDoc decryptKey(EncryptedKey encryptedKey, String JavaDoc algorithm) throws
1373                XMLEncryptionException {
1374
1375        if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Decrypting key from previously loaded EncryptedKey...");
1376
1377        if(_cipherMode != UNWRAP_MODE)
1378            if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in UNWRAP_MODE...");
1379
1380        if (algorithm == null) {
1381            throw new XMLEncryptionException("Cannot decrypt a key without knowing the algorithm");
1382        }
1383
1384        if (_key == null) {
1385
1386            if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Trying to find a KEK via key resolvers");
1387
1388            KeyInfo ki = encryptedKey.getKeyInfo();
1389            if (ki != null) {
1390                try {
1391                    _key = ki.getSecretKey();
1392                }
1393                catch (Exception JavaDoc e) {
1394                }
1395            }
1396            if (_key == null) {
1397                logger.log(java.util.logging.Level.SEVERE, "XMLCipher::decryptKey called without a KEK and cannot resolve");
1398                throw new XMLEncryptionException("Unable to decrypt without a KEK");
1399            }
1400        }
1401
1402        // Obtain the encrypted octets
1403
XMLCipherInput cipherInput = new XMLCipherInput(encryptedKey);
1404        byte [] encryptedBytes = cipherInput.getBytes();
1405
1406        String JavaDoc jceKeyAlgorithm =
1407            JCEMapper.getJCEKeyAlgorithmFromURI(algorithm);
1408
1409        Cipher c;
1410        if (_contextCipher == null) {
1411            // Now create the working cipher
1412

1413            String JavaDoc jceAlgorithm =
1414                JCEMapper.translateURItoJCEID(
1415                    encryptedKey.getEncryptionMethod().getAlgorithm());
1416
1417            if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "JCE Algorithm = " + jceAlgorithm);
1418
1419            try {
1420                            if (_requestedJCEProvider == null)
1421                c = Cipher.getInstance(jceAlgorithm);
1422                            else
1423                                c = Cipher.getInstance(jceAlgorithm, _requestedJCEProvider);
1424            } catch (NoSuchAlgorithmException JavaDoc nsae) {
1425                throw new XMLEncryptionException("empty", nsae);
1426            } catch (NoSuchProviderException JavaDoc nspre) {
1427                throw new XMLEncryptionException("empty", nspre);
1428            } catch (NoSuchPaddingException nspae) {
1429                throw new XMLEncryptionException("empty", nspae);
1430            }
1431        } else {
1432            c = _contextCipher;
1433        }
1434
1435        Key JavaDoc ret;
1436
1437        try {
1438            c.init(Cipher.UNWRAP_MODE, _key);
1439            ret = c.unwrap(encryptedBytes, jceKeyAlgorithm, Cipher.SECRET_KEY);
1440            
1441        } catch (InvalidKeyException JavaDoc ike) {
1442            throw new XMLEncryptionException("empty", ike);
1443        } catch (NoSuchAlgorithmException JavaDoc nsae) {
1444            throw new XMLEncryptionException("empty", nsae);
1445        }
1446
1447        if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Decryption of key type " + algorithm + " OK");
1448
1449        return ret;
1450
1451    }
1452        
1453    /**
1454     * Decrypt a key from a passed in EncryptedKey structure. This version
1455     * is used mainly internally, when the cipher already has an
1456     * EncryptedData loaded. The algorithm URI will be read from the
1457     * EncryptedData
1458     *
1459     * @param encryptedKey Previously loaded EncryptedKey that needs
1460     * to be decrypted.
1461     * @return a key corresponding to the give type
1462     * @throws XMLEncryptionException
1463     */

1464
1465    public Key JavaDoc decryptKey(EncryptedKey encryptedKey) throws
1466                XMLEncryptionException {
1467
1468        return decryptKey(encryptedKey, _ed.getEncryptionMethod().getAlgorithm());
1469
1470    }
1471
1472    /**
1473     * Removes the contents of a <code>Node</code>.
1474     *
1475     * @param node the <code>Node</code> to clear.
1476     */

1477    private void removeContent(Node JavaDoc node) {
1478        NodeList JavaDoc list = node.getChildNodes();
1479        if (list.getLength() > 0) {
1480            Node JavaDoc n = list.item(0);
1481            if (null != n) {
1482                n.getParentNode().removeChild(n);
1483            }
1484            removeContent(node);
1485        }
1486    }
1487
1488    /**
1489     * Decrypts <code>EncryptedData</code> in a single-part operation.
1490     *
1491     * @param element the <code>EncryptedData</code> to decrypt.
1492     * @return the <code>Node</code> as a result of the decrypt operation.
1493     * @throws XMLEncryptionException
1494     */

1495    private Document JavaDoc decryptElement(Element JavaDoc element) throws
1496            XMLEncryptionException {
1497
1498        if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Decrypting element...");
1499
1500        if(_cipherMode != DECRYPT_MODE)
1501            logger.log(java.util.logging.Level.SEVERE, "XMLCipher unexpectedly not in DECRYPT_MODE...");
1502
1503        String JavaDoc octets;
1504        try {
1505            octets = new String JavaDoc(decryptToByteArray(element), "UTF-8");
1506        } catch (UnsupportedEncodingException JavaDoc uee) {
1507            throw new XMLEncryptionException("empty", uee);
1508        }
1509
1510
1511        if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Decrypted octets:\n" + octets);
1512
1513        Node JavaDoc sourceParent = element.getParentNode();
1514
1515        DocumentFragment JavaDoc decryptedFragment =
1516            _serializer.deserialize(octets, sourceParent);
1517
1518
1519        // The de-serialiser returns a fragment whose children we need to
1520
// take on.
1521

1522        if (sourceParent instanceof Document JavaDoc) {
1523            
1524            // If this is a content decryption, this may have problems
1525

1526            _contextDocument.removeChild(_contextDocument.getDocumentElement());
1527            _contextDocument.appendChild(decryptedFragment);
1528        }
1529        else {
1530            sourceParent.replaceChild(decryptedFragment, element);
1531
1532        }
1533
1534        return (_contextDocument);
1535    }
1536    
1537
1538    /**
1539     *
1540     * @param element
1541     * @return
1542     * @throws XMLEncryptionException
1543     */

1544    private Document JavaDoc decryptElementContent(Element JavaDoc element) throws
1545            XMLEncryptionException {
1546        Element JavaDoc e = (Element JavaDoc) element.getElementsByTagNameNS(
1547            EncryptionConstants.EncryptionSpecNS,
1548            EncryptionConstants._TAG_ENCRYPTEDDATA).item(0);
1549        
1550        if (null == e) {
1551            throw new XMLEncryptionException("No EncryptedData child element.");
1552        }
1553        
1554        return (decryptElement(e));
1555    }
1556
1557    /**
1558     * Decrypt an EncryptedData element to a byte array
1559     *
1560     * When passed in an EncryptedData node, returns the decryption
1561     * as a byte array.
1562     *
1563     * Does not modify the source document
1564     * @param element
1565     * @return
1566     * @throws XMLEncryptionException
1567     */

1568
1569    public byte[] decryptToByteArray(Element JavaDoc element)
1570        throws XMLEncryptionException {
1571        
1572        if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Decrypting to ByteArray...");
1573
1574        if(_cipherMode != DECRYPT_MODE)
1575            logger.log(java.util.logging.Level.SEVERE, "XMLCipher unexpectedly not in DECRYPT_MODE...");
1576
1577        EncryptedData encryptedData = _factory.newEncryptedData(element);
1578
1579        if (_key == null) {
1580
1581            KeyInfo ki = encryptedData.getKeyInfo();
1582
1583            if (ki != null) {
1584                try {
1585                    // Add a EncryptedKey resolver
1586
ki.registerInternalKeyResolver(
1587                         new EncryptedKeyResolver(encryptedData.
1588                                                  getEncryptionMethod().
1589                                                  getAlgorithm(),
1590                                                  _kek));
1591                    _key = ki.getSecretKey();
1592                } catch (KeyResolverException kre) {
1593                    // We will throw in a second...
1594
}
1595            }
1596
1597            if (_key == null) {
1598                logger.log(java.util.logging.Level.SEVERE, "XMLCipher::decryptElement called without a key and unable to resolve");
1599
1600                throw new XMLEncryptionException("encryption.nokey");
1601            }
1602        }
1603
1604        // Obtain the encrypted octets
1605
XMLCipherInput cipherInput = new XMLCipherInput(encryptedData);
1606        byte [] encryptedBytes = cipherInput.getBytes();
1607
1608        // Now create the working cipher
1609

1610        String JavaDoc jceAlgorithm =
1611            JCEMapper.translateURItoJCEID(encryptedData.getEncryptionMethod().getAlgorithm());
1612
1613        Cipher c;
1614        try {
1615                    if (_requestedJCEProvider == null)
1616            c = Cipher.getInstance(jceAlgorithm);
1617                    else
1618                        c = Cipher.getInstance(jceAlgorithm, _requestedJCEProvider);
1619        } catch (NoSuchAlgorithmException JavaDoc nsae) {
1620            throw new XMLEncryptionException("empty", nsae);
1621        } catch (NoSuchProviderException JavaDoc nspre) {
1622            throw new XMLEncryptionException("empty", nspre);
1623        } catch (NoSuchPaddingException nspae) {
1624            throw new XMLEncryptionException("empty", nspae);
1625        }
1626
1627        // Calculate the IV length and copy out
1628

1629        // For now, we only work with Block ciphers, so this will work.
1630
// This should probably be put into the JCE mapper.
1631

1632        int ivLen = c.getBlockSize();
1633        byte[] ivBytes = new byte[ivLen];
1634
1635        // You may be able to pass the entire piece in to IvParameterSpec
1636
// and it will only take the first x bytes, but no way to be certain
1637
// that this will work for every JCE provider, so lets copy the
1638
// necessary bytes into a dedicated array.
1639

1640        System.arraycopy(encryptedBytes, 0, ivBytes, 0, ivLen);
1641        IvParameterSpec iv = new IvParameterSpec(ivBytes);
1642        
1643        try {
1644            c.init(_cipherMode, _key, iv);
1645        } catch (InvalidKeyException JavaDoc ike) {
1646            throw new XMLEncryptionException("empty", ike);
1647        } catch (InvalidAlgorithmParameterException JavaDoc iape) {
1648            throw new XMLEncryptionException("empty", iape);
1649        }
1650
1651        byte[] plainBytes;
1652
1653        try {
1654            plainBytes = c.doFinal(encryptedBytes,
1655                                   ivLen,
1656                                   encryptedBytes.length - ivLen);
1657
1658        } catch (IllegalBlockSizeException ibse) {
1659            throw new XMLEncryptionException("empty", ibse);
1660        } catch (BadPaddingException bpe) {
1661            throw new XMLEncryptionException("empty", bpe);
1662        }
1663        
1664        return (plainBytes);
1665    }
1666        
1667    /*
1668     * Expose the interface for creating XML Encryption objects
1669     */

1670
1671    /**
1672     * Creates an <code>EncryptedData</code> <code>Element</code>.
1673     *
1674     * The newEncryptedData and newEncryptedKey methods create fairly complete
1675     * elements that are immediately useable. All the other create* methods
1676     * return bare elements that still need to be built upon.
1677     *<p>
1678     * An EncryptionMethod will still need to be added however
1679     *
1680     * @param type Either REFERENCE_TYPE or VALUE_TYPE - defines what kind of
1681     * CipherData this EncryptedData will contain.
1682     * @param value the Base 64 encoded, encrypted text to wrap in the
1683     * <code>EncryptedData</code> or the URI to set in the CipherReference
1684     * (usage will depend on the <code>type</code>
1685     * @return the <code>EncryptedData</code> <code>Element</code>.
1686     *
1687     * <!--
1688     * <EncryptedData Id[OPT] Type[OPT] MimeType[OPT] Encoding[OPT]>
1689     * <EncryptionMethod/>[OPT]
1690     * <ds:KeyInfo>[OPT]
1691     * <EncryptedKey/>[OPT]
1692     * <AgreementMethod/>[OPT]
1693     * <ds:KeyName/>[OPT]
1694     * <ds:RetrievalMethod/>[OPT]
1695     * <ds:[MUL]/>[OPT]
1696     * </ds:KeyInfo>
1697     * <CipherData>[MAN]
1698     * <CipherValue/> XOR <CipherReference/>
1699     * </CipherData>
1700     * <EncryptionProperties/>[OPT]
1701     * </EncryptedData>
1702     * -->
1703     * @throws XMLEncryptionException
1704     */

1705
1706    public EncryptedData createEncryptedData(int type, String JavaDoc value) throws
1707            XMLEncryptionException {
1708        EncryptedData result = null;
1709        CipherData data = null;
1710
1711        switch (type) {
1712            case CipherData.REFERENCE_TYPE:
1713                CipherReference cipherReference = _factory.newCipherReference(
1714                    value);
1715                data = _factory.newCipherData(type);
1716                data.setCipherReference(cipherReference);
1717                result = _factory.newEncryptedData(data);
1718                break;
1719            case CipherData.VALUE_TYPE:
1720                CipherValue cipherValue = _factory.newCipherValue(value);
1721                data = _factory.newCipherData(type);
1722                data.setCipherValue(cipherValue);
1723                result = _factory.newEncryptedData(data);
1724        }
1725
1726        return (result);
1727    }
1728
1729    /**
1730     * Creates an <code>EncryptedKey</code> <code>Element</code>.
1731     *
1732     * The newEncryptedData and newEncryptedKey methods create fairly complete
1733     * elements that are immediately useable. All the other create* methods
1734     * return bare elements that still need to be built upon.
1735     *<p>
1736     * An EncryptionMethod will still need to be added however
1737     *
1738     * @param type Either REFERENCE_TYPE or VALUE_TYPE - defines what kind of
1739     * CipherData this EncryptedData will contain.
1740     * @param value the Base 64 encoded, encrypted text to wrap in the
1741     * <code>EncryptedKey</code> or the URI to set in the CipherReference
1742     * (usage will depend on the <code>type</code>
1743     * @return the <code>EncryptedKey</code> <code>Element</code>.
1744     *
1745     * <!--
1746     * <EncryptedKey Id[OPT] Type[OPT] MimeType[OPT] Encoding[OPT]>
1747     * <EncryptionMethod/>[OPT]
1748     * <ds:KeyInfo>[OPT]
1749     * <EncryptedKey/>[OPT]
1750     * <AgreementMethod/>[OPT]
1751     * <ds:KeyName/>[OPT]
1752     * <ds:RetrievalMethod/>[OPT]
1753     * <ds:[MUL]/>[OPT]
1754     * </ds:KeyInfo>
1755     * <CipherData>[MAN]
1756     * <CipherValue/> XOR <CipherReference/>
1757     * </CipherData>
1758     * <EncryptionProperties/>[OPT]
1759     * </EncryptedData>
1760     * -->
1761     * @throws XMLEncryptionException
1762     */

1763
1764    public EncryptedKey createEncryptedKey(int type, String JavaDoc value) throws
1765            XMLEncryptionException {
1766        EncryptedKey result = null;
1767        CipherData data = null;
1768
1769        switch (type) {
1770            case CipherData.REFERENCE_TYPE:
1771                CipherReference cipherReference = _factory.newCipherReference(
1772                    value);
1773                data = _factory.newCipherData(type);
1774                data.setCipherReference(cipherReference);
1775                result = _factory.newEncryptedKey(data);
1776                break;
1777            case CipherData.VALUE_TYPE:
1778                CipherValue cipherValue = _factory.newCipherValue(value);
1779                data = _factory.newCipherData(type);
1780                data.setCipherValue(cipherValue);
1781                result = _factory.newEncryptedKey(data);
1782        }
1783
1784        return (result);
1785    }
1786
1787    /**
1788     * Create an AgreementMethod object
1789     *
1790     * @param algorithm Algorithm of the agreement method
1791     * @return
1792     */

1793
1794    public AgreementMethod createAgreementMethod(String JavaDoc algorithm) {
1795        return (_factory.newAgreementMethod(algorithm));
1796    }
1797
1798    /**
1799     * Create a CipherData object
1800     *
1801     * @param type Type of this CipherData (either VALUE_TUPE or
1802     * REFERENCE_TYPE)
1803     * @return
1804     */

1805
1806    public CipherData createCipherData(int type) {
1807        return (_factory.newCipherData(type));
1808    }
1809
1810    /**
1811     * Create a CipherReference object
1812     *
1813     * @return
1814     * @param uri The URI that the reference will refer
1815     */

1816
1817    public CipherReference createCipherReference(String JavaDoc uri) {
1818        return (_factory.newCipherReference(uri));
1819    }
1820    
1821    /**
1822     * Create a CipherValue element
1823     *
1824     * @param value The value to set the ciphertext to
1825     * @return
1826     */

1827
1828    public CipherValue createCipherValue(String JavaDoc value) {
1829        return (_factory.newCipherValue(value));
1830    }
1831
1832    /**
1833     * Create an EncryptedMethod object
1834     *
1835     * @param algorithm Algorithm for the encryption
1836     * @return
1837     */

1838    public EncryptionMethod createEncryptionMethod(String JavaDoc algorithm) {
1839        return (_factory.newEncryptionMethod(algorithm));
1840    }
1841
1842    /**
1843     * Create an EncryptedProperties element
1844     * @return
1845     */

1846    public EncryptionProperties createEncryptionProperties() {
1847        return (_factory.newEncryptionProperties());
1848    }
1849
1850    /**
1851     * Create a new EncryptionProperty element
1852     * @return
1853     */

1854    public EncryptionProperty createEncryptionProperty() {
1855        return (_factory.newEncryptionProperty());
1856    }
1857
1858    /**
1859     * Create a new ReferenceList object
1860     * @return
1861     * @param type
1862     */

1863    public ReferenceList createReferenceList(int type) {
1864        return (_factory.newReferenceList(type));
1865    }
1866    
1867    /**
1868     * Create a new Transforms object
1869     * <p>
1870     * <b>Note</b>: A context document <i>must</i> have been set
1871     * elsewhere (possibly via a call to doFinal). If not, use the
1872     * createTransforms(Document) method.
1873     * @return
1874     */

1875
1876    public Transforms createTransforms() {
1877        return (_factory.newTransforms());
1878    }
1879
1880    /**
1881     * Create a new Transforms object
1882     *
1883     * Because the handling of Transforms is currently done in the signature
1884     * code, the creation of a Transforms object <b>requires</b> a
1885     * context document.
1886     *
1887     * @param doc Document that will own the created Transforms node
1888     * @return
1889     */

1890    public Transforms createTransforms(Document JavaDoc doc) {
1891        return (_factory.newTransforms(doc));
1892    }
1893
1894    /**
1895     * Converts <code>String</code>s into <code>Node</code>s and visa versa.
1896     * <p>
1897     * <b>NOTE:</b> For internal use only.
1898     *
1899     * @author Axl Mattheus
1900     */

1901
1902    private class Serializer {
1903        /**
1904         * Initialize the <code>XMLSerializer</code> with the specified context
1905         * <code>Document</code>.
1906         * <p/>
1907         * Setup OutputFormat in a way that the serialization does <b>not</b>
1908         * modifiy the contents, that is it shall not do any pretty printing
1909         * and so on. This would destroy the original content before
1910         * encryption. If that content was signed before encryption and the
1911         * serialization modifies the content the signature verification will
1912         * fail.
1913         */

1914        Serializer() {
1915        }
1916
1917        /**
1918         * Returns a <code>String</code> representation of the specified
1919         * <code>Document</code>.
1920         * <p/>
1921         * Refer also to comments about setup of format.
1922         *
1923         * @param document the <code>Document</code> to serialize.
1924         * @return the <code>String</code> representation of the serilaized
1925         * <code>Document</code>.
1926         * @throws Exception
1927         */

1928        String JavaDoc serialize(Document JavaDoc document) throws Exception JavaDoc {
1929            return canonSerialize(document);
1930        }
1931
1932        /**
1933         * Returns a <code>String</code> representation of the specified
1934         * <code>Element</code>.
1935         * <p/>
1936         * Refer also to comments about setup of format.
1937         *
1938         * @param element the <code>Element</code> to serialize.
1939         * @return the <code>String</code> representation of the serilaized
1940         * <code>Element</code>.
1941         * @throws Exception
1942         */

1943        String JavaDoc serialize(Element JavaDoc element) throws Exception JavaDoc {
1944            return canonSerialize(element);
1945        }
1946
1947        /**
1948         * Returns a <code>String</code> representation of the specified
1949         * <code>NodeList</code>.
1950         * <p/>
1951         * This is a special case because the NodeList may represent a
1952         * <code>DocumentFragment</code>. A document fragement may be a
1953         * non-valid XML document (refer to appropriate description of
1954         * W3C) because it my start with a non-element node, e.g. a text
1955         * node.
1956         * <p/>
1957         * The methods first converts the node list into a document fragment.
1958         * Special care is taken to not destroy the current document, thus
1959         * the method clones the nodes (deep cloning) before it appends
1960         * them to the document fragment.
1961         * <p/>
1962         * Refer also to comments about setup of format.
1963         *
1964         * @param content the <code>NodeList</code> to serialize.
1965         * @return the <code>String</code> representation of the serilaized
1966         * <code>NodeList</code>.
1967         * @throws Exception
1968         */

1969        String JavaDoc serialize(NodeList JavaDoc content) throws Exception JavaDoc { //XMLEncryptionException {
1970
ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
1971            _canon.setWriter(baos);
1972            _canon.notReset();
1973            for (int i = 0; i < content.getLength(); i++) {
1974                _canon.canonicalizeSubtree(content.item(i));
1975            }
1976            baos.close();
1977            return baos.toString("UTF-8");
1978        }
1979
1980        /**
1981         * Use the Canoncializer to serialize the node
1982         * @param node
1983         * @return
1984         * @throws Exception
1985         */

1986        String JavaDoc canonSerialize(Node JavaDoc node) throws Exception JavaDoc {
1987            ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
1988            _canon.setWriter(baos);
1989            _canon.notReset();
1990            _canon.canonicalizeSubtree(node);
1991            baos.close();
1992            return baos.toString("UTF-8");
1993        }
1994        /**
1995         * @param source
1996         * @param ctx
1997         * @return
1998         * @throws XMLEncryptionException
1999         *
2000         */

2001        DocumentFragment JavaDoc deserialize(String JavaDoc source, Node JavaDoc ctx) throws XMLEncryptionException {
2002            DocumentFragment JavaDoc result;
2003            final String JavaDoc tagname = "fragment";
2004
2005            // Create the context to parse the document against
2006
StringBuffer JavaDoc sb;
2007            
2008            sb = new StringBuffer JavaDoc();
2009            sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><"+tagname);
2010            
2011            // Run through each node up to the document node and find any
2012
// xmlns: nodes
2013

2014            Node JavaDoc wk = ctx;
2015            
2016            while (wk != null) {
2017
2018                NamedNodeMap JavaDoc atts = wk.getAttributes();
2019                int length;
2020                if (atts != null)
2021                    length = atts.getLength();
2022                else
2023                    length = 0;
2024
2025                for (int i = 0 ; i < length ; ++i) {
2026                    Node JavaDoc att = atts.item(i);
2027                    if (att.getNodeName().startsWith("xmlns:") ||
2028                        att.getNodeName().equals("xmlns")) {
2029                    
2030                        // Check to see if this node has already been found
2031
Node JavaDoc p = ctx;
2032                        boolean found = false;
2033                        while (p != wk) {
2034                            NamedNodeMap JavaDoc tstAtts = p.getAttributes();
2035                            if (tstAtts != null &&
2036                                tstAtts.getNamedItem(att.getNodeName()) != null) {
2037                                found = true;
2038                                break;
2039                            }
2040                            p = p.getParentNode();
2041                        }
2042                        if (found == false) {
2043                            
2044                            // This is an attribute node
2045
sb.append(" " + att.getNodeName() + "=\"" +
2046                                      att.getNodeValue() + "\"");
2047                        }
2048                    }
2049                }
2050                wk = wk.getParentNode();
2051            }
2052            sb.append(">" + source + "</" + tagname + ">");
2053            String JavaDoc fragment = sb.toString();
2054
2055            try {
2056                DocumentBuilderFactory JavaDoc dbf =
2057                    DocumentBuilderFactory.newInstance();
2058                dbf.setNamespaceAware(true);
2059                dbf.setAttribute("http://xml.org/sax/features/namespaces", Boolean.TRUE);
2060                DocumentBuilder JavaDoc db = dbf.newDocumentBuilder();
2061                Document JavaDoc d = db.parse(
2062                    new InputSource JavaDoc(new StringReader JavaDoc(fragment)));
2063
2064                Element JavaDoc fragElt = (Element JavaDoc) _contextDocument.importNode(
2065                         d.getDocumentElement(), true);
2066                result = _contextDocument.createDocumentFragment();
2067                Node JavaDoc child = fragElt.getFirstChild();
2068                while (child != null) {
2069                    fragElt.removeChild(child);
2070                    result.appendChild(child);
2071                    child = fragElt.getFirstChild();
2072                }
2073                // String outp = serialize(d);
2074

2075            } catch (SAXException JavaDoc se) {
2076                throw new XMLEncryptionException("empty", se);
2077            } catch (ParserConfigurationException JavaDoc pce) {
2078                throw new XMLEncryptionException("empty", pce);
2079            } catch (IOException JavaDoc ioe) {
2080                throw new XMLEncryptionException("empty", ioe);
2081            }
2082
2083            return (result);
2084        }
2085    }
2086
2087
2088    /**
2089     *
2090     * @author Axl Mattheus
2091     */

2092    private class Factory {
2093        /**
2094         * @param algorithm
2095         * @return
2096         *
2097         */

2098        AgreementMethod newAgreementMethod(String JavaDoc algorithm) {
2099            return (new AgreementMethodImpl(algorithm));
2100        }
2101
2102        /**
2103         * @param type
2104         * @return
2105         *
2106         */

2107        CipherData newCipherData(int type) {
2108            return (new CipherDataImpl(type));
2109        }
2110
2111        /**
2112         * @param uri
2113         * @return
2114         *
2115         */

2116        CipherReference newCipherReference(String JavaDoc uri) {
2117            return (new CipherReferenceImpl(uri));
2118        }
2119
2120        /**
2121         * @param value
2122         * @return
2123         *
2124         */

2125        CipherValue newCipherValue(String JavaDoc value) {
2126            return (new CipherValueImpl(value));
2127        }
2128
2129        /**
2130         *
2131         
2132        CipherValue newCipherValue(byte[] value) {
2133            return (new CipherValueImpl(value));
2134        }
2135        */

2136        /**
2137         * @param data
2138         * @return
2139         *
2140         */

2141        EncryptedData newEncryptedData(CipherData data) {
2142            return (new EncryptedDataImpl(data));
2143        }
2144
2145        /**
2146         * @param data
2147         * @return
2148         *
2149         */

2150        EncryptedKey newEncryptedKey(CipherData data) {
2151            return (new EncryptedKeyImpl(data));
2152        }
2153
2154        /**
2155         * @param algorithm
2156         * @return
2157         *
2158         */

2159        EncryptionMethod newEncryptionMethod(String JavaDoc algorithm) {
2160            return (new EncryptionMethodImpl(algorithm));
2161        }
2162
2163        /**
2164         * @return
2165         *
2166         */

2167        EncryptionProperties newEncryptionProperties() {
2168            return (new EncryptionPropertiesImpl());
2169        }
2170
2171        /**
2172         * @return
2173         *
2174         */

2175        EncryptionProperty newEncryptionProperty() {
2176            return (new EncryptionPropertyImpl());
2177        }
2178
2179        /**
2180         * @param type
2181         * @return
2182         *
2183         */

2184        ReferenceList newReferenceList(int type) {
2185            return (new ReferenceListImpl(type));
2186        }
2187
2188        /**
2189         * @return
2190         *
2191         */

2192        Transforms newTransforms() {
2193            return (new TransformsImpl());
2194        }
2195
2196        /**
2197         * @param doc
2198         * @return
2199         *
2200         */

2201        Transforms newTransforms(Document JavaDoc doc) {
2202            return (new TransformsImpl(doc));
2203        }
2204
2205        /**
2206         * @param element
2207         * @return
2208         * @throws XMLEncryptionException
2209         *
2210         */

2211        // <element name="AgreementMethod" type="xenc:AgreementMethodType"/>
2212
// <complexType name="AgreementMethodType" mixed="true">
2213
// <sequence>
2214
// <element name="KA-Nonce" minOccurs="0" type="base64Binary"/>
2215
// <!-- <element ref="ds:DigestMethod" minOccurs="0"/> -->
2216
// <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
2217
// <element name="OriginatorKeyInfo" minOccurs="0" type="ds:KeyInfoType"/>
2218
// <element name="RecipientKeyInfo" minOccurs="0" type="ds:KeyInfoType"/>
2219
// </sequence>
2220
// <attribute name="Algorithm" type="anyURI" use="required"/>
2221
// </complexType>
2222
AgreementMethod newAgreementMethod(Element JavaDoc element) throws
2223                XMLEncryptionException {
2224            if (null == element) {
2225                //complain
2226
}
2227
2228            String JavaDoc algorithm = element.getAttributeNS(null,
2229                EncryptionConstants._ATT_ALGORITHM);
2230            AgreementMethod result = newAgreementMethod(algorithm);
2231
2232            Element JavaDoc kaNonceElement = (Element JavaDoc) element.getElementsByTagNameNS(
2233                EncryptionConstants.EncryptionSpecNS,
2234                EncryptionConstants._TAG_KA_NONCE).item(0);
2235            if (null != kaNonceElement) {
2236                result.setKANonce(kaNonceElement.getNodeValue().getBytes());
2237            }
2238            // TODO: ///////////////////////////////////////////////////////////
2239
// Figure out how to make this pesky line work..
2240
// <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
2241

2242            // TODO: Work out how to handle relative URI
2243

2244            Element JavaDoc originatorKeyInfoElement =
2245                (Element JavaDoc) element.getElementsByTagNameNS(
2246                    EncryptionConstants.EncryptionSpecNS,
2247                    EncryptionConstants._TAG_ORIGINATORKEYINFO).item(0);
2248            if (null != originatorKeyInfoElement) {
2249                try {
2250                    result.setOriginatorKeyInfo(
2251                        new KeyInfo(originatorKeyInfoElement, null));
2252                } catch (XMLSecurityException xse) {
2253                    throw new XMLEncryptionException("empty", xse);
2254                }
2255            }
2256
2257            // TODO: Work out how to handle relative URI
2258

2259            Element JavaDoc recipientKeyInfoElement =
2260                (Element JavaDoc) element.getElementsByTagNameNS(
2261                    EncryptionConstants.EncryptionSpecNS,
2262                    EncryptionConstants._TAG_RECIPIENTKEYINFO).item(0);
2263            if (null != recipientKeyInfoElement) {
2264                try {
2265                    result.setRecipientKeyInfo(
2266                        new KeyInfo(recipientKeyInfoElement, null));
2267                } catch (XMLSecurityException xse) {
2268                    throw new XMLEncryptionException("empty", xse);
2269                }
2270            }
2271
2272            return (result);
2273        }
2274
2275        /**
2276         * @param element
2277         * @return
2278         * @throws XMLEncryptionException
2279         *
2280         */

2281        // <element name='CipherData' type='xenc:CipherDataType'/>
2282
// <complexType name='CipherDataType'>
2283
// <choice>
2284
// <element name='CipherValue' type='base64Binary'/>
2285
// <element ref='xenc:CipherReference'/>
2286
// </choice>
2287
// </complexType>
2288
CipherData newCipherData(Element JavaDoc element) throws
2289                XMLEncryptionException {
2290            if (null == element) {
2291                // complain
2292
}
2293
2294            int type = 0;
2295            Element JavaDoc e = null;
2296            if (element.getElementsByTagNameNS(
2297                EncryptionConstants.EncryptionSpecNS,
2298                EncryptionConstants._TAG_CIPHERVALUE).getLength() > 0) {
2299                type = CipherData.VALUE_TYPE;
2300                e = (Element JavaDoc) element.getElementsByTagNameNS(
2301                    EncryptionConstants.EncryptionSpecNS,
2302                    EncryptionConstants._TAG_CIPHERVALUE).item(0);
2303            } else if (element.getElementsByTagNameNS(
2304                EncryptionConstants.EncryptionSpecNS,
2305                EncryptionConstants._TAG_CIPHERREFERENCE).getLength() > 0) {
2306                type = CipherData.REFERENCE_TYPE;
2307                e = (Element JavaDoc) element.getElementsByTagNameNS(
2308                    EncryptionConstants.EncryptionSpecNS,
2309                    EncryptionConstants._TAG_CIPHERREFERENCE).item(0);
2310            }
2311
2312            CipherData result = newCipherData(type);
2313            if (type == CipherData.VALUE_TYPE) {
2314                result.setCipherValue(newCipherValue(e));
2315            } else if (type == CipherData.REFERENCE_TYPE) {
2316                result.setCipherReference(newCipherReference(e));
2317            }
2318
2319            return (result);
2320        }
2321
2322        /**
2323         * @param element
2324         * @return
2325         * @throws XMLEncryptionException
2326         *
2327         */

2328        // <element name='CipherReference' type='xenc:CipherReferenceType'/>
2329
// <complexType name='CipherReferenceType'>
2330
// <sequence>
2331
// <element name='Transforms' type='xenc:TransformsType' minOccurs='0'/>
2332
// </sequence>
2333
// <attribute name='URI' type='anyURI' use='required'/>
2334
// </complexType>
2335
CipherReference newCipherReference(Element JavaDoc element) throws
2336                XMLEncryptionException {
2337
2338            Attr JavaDoc URIAttr =
2339                element.getAttributeNodeNS(null, EncryptionConstants._ATT_URI);
2340            CipherReference result = new CipherReferenceImpl(URIAttr);
2341
2342            // Find any Transforms
2343

2344            NodeList JavaDoc transformsElements = element.getElementsByTagNameNS(
2345                    EncryptionConstants.EncryptionSpecNS,
2346                    EncryptionConstants._TAG_TRANSFORMS);
2347            Element JavaDoc transformsElement =
2348                (Element JavaDoc) transformsElements.item(0);
2349            
2350            if (transformsElement != null) {
2351                if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Creating a DSIG based Transforms element");
2352                try {
2353                    result.setTransforms(new TransformsImpl(transformsElement));
2354                }
2355                catch (XMLSignatureException xse) {
2356                    throw new XMLEncryptionException("empty", xse);
2357                } catch (InvalidTransformException ite) {
2358                    throw new XMLEncryptionException("empty", ite);
2359                } catch (XMLSecurityException xse) {
2360                    throw new XMLEncryptionException("empty", xse);
2361                }
2362
2363            }
2364
2365            return result;
2366        }
2367
2368        /**
2369         * @param element
2370         * @return
2371         *
2372         */

2373        CipherValue newCipherValue(Element JavaDoc element) {
2374            String JavaDoc value = XMLUtils.getFullTextChildrenFromElement(element);
2375
2376            CipherValue result = newCipherValue(value);
2377
2378            return (result);
2379        }
2380
2381        /**
2382         * @param element
2383         * @return
2384         * @throws XMLEncryptionException
2385         *
2386         */

2387        // <complexType name='EncryptedType' abstract='true'>
2388
// <sequence>
2389
// <element name='EncryptionMethod' type='xenc:EncryptionMethodType'
2390
// minOccurs='0'/>
2391
// <element ref='ds:KeyInfo' minOccurs='0'/>
2392
// <element ref='xenc:CipherData'/>
2393
// <element ref='xenc:EncryptionProperties' minOccurs='0'/>
2394
// </sequence>
2395
// <attribute name='Id' type='ID' use='optional'/>
2396
// <attribute name='Type' type='anyURI' use='optional'/>
2397
// <attribute name='MimeType' type='string' use='optional'/>
2398
// <attribute name='Encoding' type='anyURI' use='optional'/>
2399
// </complexType>
2400
// <element name='EncryptedData' type='xenc:EncryptedDataType'/>
2401
// <complexType name='EncryptedDataType'>
2402
// <complexContent>
2403
// <extension base='xenc:EncryptedType'/>
2404
// </complexContent>
2405
// </complexType>
2406
EncryptedData newEncryptedData(Element JavaDoc element) throws
2407            XMLEncryptionException {
2408            EncryptedData result = null;
2409
2410            NodeList JavaDoc dataElements = element.getElementsByTagNameNS(
2411                    EncryptionConstants.EncryptionSpecNS,
2412                    EncryptionConstants._TAG_CIPHERDATA);
2413
2414            // Need to get the last CipherData found, as earlier ones will
2415
// be for elements in the KeyInfo lists
2416

2417            Element JavaDoc dataElement =
2418                (Element JavaDoc) dataElements.item(dataElements.getLength() - 1);
2419
2420            CipherData data = newCipherData(dataElement);
2421
2422            result = newEncryptedData(data);
2423
2424            try {
2425                result.setId(element.getAttributeNS(
2426                    null, EncryptionConstants._ATT_ID));
2427                result.setType(new URI(
2428                    element.getAttributeNS(
2429                        null, EncryptionConstants._ATT_TYPE)).toString());
2430                result.setMimeType(element.getAttributeNS(
2431                    null, EncryptionConstants._ATT_MIMETYPE));
2432                result.setEncoding(new URI(
2433                    element.getAttributeNS(
2434                        null, Constants._ATT_ENCODING)).toString());
2435            } catch (URI.MalformedURIException mfue) {
2436                // do nothing
2437
}
2438
2439            Element JavaDoc encryptionMethodElement =
2440                (Element JavaDoc) element.getElementsByTagNameNS(
2441                    EncryptionConstants.EncryptionSpecNS,
2442                    EncryptionConstants._TAG_ENCRYPTIONMETHOD).item(0);
2443            if (null != encryptionMethodElement) {
2444                result.setEncryptionMethod(newEncryptionMethod(
2445                    encryptionMethodElement));
2446            }
2447
2448            // BFL 16/7/03 - simple implementation
2449
// TODO: Work out how to handle relative URI
2450

2451            Element JavaDoc keyInfoElement =
2452                (Element JavaDoc) element.getElementsByTagNameNS(
2453                    Constants.SignatureSpecNS, Constants._TAG_KEYINFO).item(0);
2454            if (null != keyInfoElement) {
2455                try {
2456                    result.setKeyInfo(new KeyInfo(keyInfoElement, null));
2457                } catch (XMLSecurityException xse) {
2458                    throw new XMLEncryptionException("Error loading Key Info",
2459                                                     xse);
2460                }
2461            }
2462
2463            // TODO: Implement
2464
Element JavaDoc encryptionPropertiesElement =
2465                (Element JavaDoc) element.getElementsByTagNameNS(
2466                    EncryptionConstants.EncryptionSpecNS,
2467                    EncryptionConstants._TAG_ENCRYPTIONPROPERTIES).item(0);
2468            if (null != encryptionPropertiesElement) {
2469                result.setEncryptionProperties(
2470                    newEncryptionProperties(encryptionPropertiesElement));
2471            }
2472
2473            return (result);
2474        }
2475
2476        /**
2477         * @param element
2478         * @return
2479         * @throws XMLEncryptionException
2480         *
2481         */

2482        // <complexType name='EncryptedType' abstract='true'>
2483
// <sequence>
2484
// <element name='EncryptionMethod' type='xenc:EncryptionMethodType'
2485
// minOccurs='0'/>
2486
// <element ref='ds:KeyInfo' minOccurs='0'/>
2487
// <element ref='xenc:CipherData'/>
2488
// <element ref='xenc:EncryptionProperties' minOccurs='0'/>
2489
// </sequence>
2490
// <attribute name='Id' type='ID' use='optional'/>
2491
// <attribute name='Type' type='anyURI' use='optional'/>
2492
// <attribute name='MimeType' type='string' use='optional'/>
2493
// <attribute name='Encoding' type='anyURI' use='optional'/>
2494
// </complexType>
2495
// <element name='EncryptedKey' type='xenc:EncryptedKeyType'/>
2496
// <complexType name='EncryptedKeyType'>
2497
// <complexContent>
2498
// <extension base='xenc:EncryptedType'>
2499
// <sequence>
2500
// <element ref='xenc:ReferenceList' minOccurs='0'/>
2501
// <element name='CarriedKeyName' type='string' minOccurs='0'/>
2502
// </sequence>
2503
// <attribute name='Recipient' type='string' use='optional'/>
2504
// </extension>
2505
// </complexContent>
2506
// </complexType>
2507
EncryptedKey newEncryptedKey(Element JavaDoc element) throws
2508                XMLEncryptionException {
2509            EncryptedKey result = null;
2510            NodeList JavaDoc dataElements = element.getElementsByTagNameNS(
2511                    EncryptionConstants.EncryptionSpecNS,
2512                    EncryptionConstants._TAG_CIPHERDATA);
2513            Element JavaDoc dataElement =
2514                (Element JavaDoc) dataElements.item(dataElements.getLength() - 1);
2515
2516            CipherData data = newCipherData(dataElement);
2517            result = newEncryptedKey(data);
2518
2519            try {
2520                result.setId(element.getAttributeNS(
2521                    null, EncryptionConstants._ATT_ID));
2522                result.setType(new URI(
2523                    element.getAttributeNS(
2524                        null, EncryptionConstants._ATT_TYPE)).toString());
2525                result.setMimeType(element.getAttributeNS(
2526                    null, EncryptionConstants._ATT_MIMETYPE));
2527                result.setEncoding(new URI(
2528                    element.getAttributeNS(
2529                        null, Constants._ATT_ENCODING)).toString());
2530                result.setRecipient(element.getAttributeNS(
2531                    null, EncryptionConstants._ATT_RECIPIENT));
2532            } catch (URI.MalformedURIException mfue) {
2533                // do nothing
2534
}
2535
2536            Element JavaDoc encryptionMethodElement =
2537                (Element JavaDoc) element.getElementsByTagNameNS(
2538                    EncryptionConstants.EncryptionSpecNS,
2539                    EncryptionConstants._TAG_ENCRYPTIONMETHOD).item(0);
2540            if (null != encryptionMethodElement) {
2541                result.setEncryptionMethod(newEncryptionMethod(
2542                    encryptionMethodElement));
2543            }
2544
2545            Element JavaDoc keyInfoElement =
2546                (Element JavaDoc) element.getElementsByTagNameNS(
2547                    Constants.SignatureSpecNS, Constants._TAG_KEYINFO).item(0);
2548            if (null != keyInfoElement) {
2549                try {
2550                    result.setKeyInfo(new KeyInfo(keyInfoElement, null));
2551                } catch (XMLSecurityException xse) {
2552                    throw new XMLEncryptionException("Error loading Key Info",
2553                                                     xse);
2554                }
2555            }
2556
2557            // TODO: Implement
2558
Element JavaDoc encryptionPropertiesElement =
2559                (Element JavaDoc) element.getElementsByTagNameNS(
2560                    EncryptionConstants.EncryptionSpecNS,
2561                    EncryptionConstants._TAG_ENCRYPTIONPROPERTIES).item(0);
2562            if (null != encryptionPropertiesElement) {
2563                result.setEncryptionProperties(
2564                    newEncryptionProperties(encryptionPropertiesElement));
2565            }
2566
2567            Element JavaDoc referenceListElement =
2568                (Element JavaDoc) element.getElementsByTagNameNS(
2569                    EncryptionConstants.EncryptionSpecNS,
2570                    EncryptionConstants._TAG_REFERENCELIST).item(0);
2571            if (null != referenceListElement) {
2572                result.setReferenceList(newReferenceList(referenceListElement));
2573            }
2574
2575            Element JavaDoc carriedNameElement =
2576                (Element JavaDoc) element.getElementsByTagNameNS(
2577                    EncryptionConstants.EncryptionSpecNS,
2578                    EncryptionConstants._TAG_CARRIEDKEYNAME).item(0);
2579            if (null != carriedNameElement) {
2580                result.setCarriedName(carriedNameElement.getNodeValue());
2581            }
2582
2583            return (result);
2584        }
2585
2586        /**
2587         * @param element
2588         * @return
2589         *
2590         */

2591        // <complexType name='EncryptionMethodType' mixed='true'>
2592
// <sequence>
2593
// <element name='KeySize' minOccurs='0' type='xenc:KeySizeType'/>
2594
// <element name='OAEPparams' minOccurs='0' type='base64Binary'/>
2595
// <any namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
2596
// </sequence>
2597
// <attribute name='Algorithm' type='anyURI' use='required'/>
2598
// </complexType>
2599
EncryptionMethod newEncryptionMethod(Element JavaDoc element) {
2600            String JavaDoc algorithm = element.getAttributeNS(
2601                null, EncryptionConstants._ATT_ALGORITHM);
2602            EncryptionMethod result = newEncryptionMethod(algorithm);
2603
2604            Element JavaDoc keySizeElement =
2605                (Element JavaDoc) element.getElementsByTagNameNS(
2606                    EncryptionConstants.EncryptionSpecNS,
2607                    EncryptionConstants._TAG_KEYSIZE).item(0);
2608            if (null != keySizeElement) {
2609                result.setKeySize(
2610                    Integer.valueOf(
2611                        keySizeElement.getFirstChild().getNodeValue()).intValue());
2612            }
2613
2614            Element JavaDoc oaepParamsElement =
2615                (Element JavaDoc) element.getElementsByTagNameNS(
2616                    EncryptionConstants.EncryptionSpecNS,
2617                    EncryptionConstants._TAG_OAEPPARAMS).item(0);
2618            if (null != oaepParamsElement) {
2619                result.setOAEPparams(
2620                    oaepParamsElement.getNodeValue().getBytes());
2621            }
2622
2623            // TODO: Make this mess work
2624
// <any namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
2625

2626            return (result);
2627        }
2628
2629        /**
2630         * @param element
2631         * @return
2632         *
2633         */

2634        // <element name='EncryptionProperties' type='xenc:EncryptionPropertiesType'/>
2635
// <complexType name='EncryptionPropertiesType'>
2636
// <sequence>
2637
// <element ref='xenc:EncryptionProperty' maxOccurs='unbounded'/>
2638
// </sequence>
2639
// <attribute name='Id' type='ID' use='optional'/>
2640
// </complexType>
2641
EncryptionProperties newEncryptionProperties(Element JavaDoc element) {
2642            EncryptionProperties result = newEncryptionProperties();
2643
2644            result.setId(element.getAttributeNS(
2645                null, EncryptionConstants._ATT_ID));
2646
2647            NodeList JavaDoc encryptionPropertyList =
2648                element.getElementsByTagNameNS(
2649                    EncryptionConstants.EncryptionSpecNS,
2650                    EncryptionConstants._TAG_ENCRYPTIONPROPERTY);
2651            for(int i = 0; i < encryptionPropertyList.getLength(); i++) {
2652                Node JavaDoc n = encryptionPropertyList.item(i);
2653                if (null != n) {
2654                    result.addEncryptionProperty(
2655                        newEncryptionProperty((Element JavaDoc) n));
2656                }
2657            }
2658
2659            return (result);
2660        }
2661
2662        /**
2663         * @param element
2664         * @return
2665         *
2666         */

2667        // <element name='EncryptionProperty' type='xenc:EncryptionPropertyType'/>
2668
// <complexType name='EncryptionPropertyType' mixed='true'>
2669
// <choice maxOccurs='unbounded'>
2670
// <any namespace='##other' processContents='lax'/>
2671
// </choice>
2672
// <attribute name='Target' type='anyURI' use='optional'/>
2673
// <attribute name='Id' type='ID' use='optional'/>
2674
// <anyAttribute namespace="http://www.w3.org/XML/1998/namespace"/>
2675
// </complexType>
2676
EncryptionProperty newEncryptionProperty(Element JavaDoc element) {
2677            EncryptionProperty result = newEncryptionProperty();
2678
2679            try {
2680                result.setTarget(new URI(
2681                    element.getAttributeNS(
2682                        null, EncryptionConstants._ATT_TARGET)).toString());
2683            } catch (URI.MalformedURIException mfue) {
2684                // do nothing
2685
}
2686            result.setId(element.getAttributeNS(
2687                null, EncryptionConstants._ATT_ID));
2688            // TODO: Make this lot work...
2689
// <anyAttribute namespace="http://www.w3.org/XML/1998/namespace"/>
2690

2691            // TODO: Make this work...
2692
// <any namespace='##other' processContents='lax'/>
2693

2694            return (result);
2695        }
2696
2697        /**
2698         * @param element
2699         * @return
2700         *
2701         */

2702        // <element name='ReferenceList'>
2703
// <complexType>
2704
// <choice minOccurs='1' maxOccurs='unbounded'>
2705
// <element name='DataReference' type='xenc:ReferenceType'/>
2706
// <element name='KeyReference' type='xenc:ReferenceType'/>
2707
// </choice>
2708
// </complexType>
2709
// </element>
2710
ReferenceList newReferenceList(Element JavaDoc element) {
2711            int type = 0;
2712            if (null != element.getElementsByTagNameNS(
2713                EncryptionConstants.EncryptionSpecNS,
2714                EncryptionConstants._TAG_DATAREFERENCE).item(0)) {
2715                type = ReferenceList.DATA_REFERENCE;
2716            } else if (null != element.getElementsByTagNameNS(
2717                EncryptionConstants.EncryptionSpecNS,
2718                EncryptionConstants._TAG_KEYREFERENCE).item(0)) {
2719                type = ReferenceList.KEY_REFERENCE;
2720            } else {
2721                // complain
2722
}
2723
2724            ReferenceList result = new ReferenceListImpl(type);
2725            NodeList JavaDoc list = null;
2726            switch (type) {
2727            case ReferenceList.DATA_REFERENCE:
2728                list = element.getElementsByTagNameNS(
2729                    EncryptionConstants.EncryptionSpecNS,
2730                    EncryptionConstants._TAG_DATAREFERENCE);
2731                for (int i = 0; i < list.getLength() ; i++) {
2732            String JavaDoc uri = ((Element JavaDoc) list.item(i)).getAttribute("URI");
2733                    result.add(result.newDataReference(uri));
2734                }
2735        break;
2736            case ReferenceList.KEY_REFERENCE:
2737                list = element.getElementsByTagNameNS(
2738                    EncryptionConstants.EncryptionSpecNS,
2739                    EncryptionConstants._TAG_KEYREFERENCE);
2740                for (int i = 0; i < list.getLength() ; i++) {
2741                    String JavaDoc uri = ((Element JavaDoc) list.item(i)).getAttribute("URI");
2742                    result.add(result.newKeyReference(uri));
2743                }
2744            }
2745
2746            return (result);
2747        }
2748
2749        /**
2750         * @param element
2751         * @return
2752         *
2753         */

2754        Transforms newTransforms(Element JavaDoc element) {
2755            return (null);
2756        }
2757
2758        /**
2759         * @param agreementMethod
2760         * @return
2761         *
2762         */

2763        Element JavaDoc toElement(AgreementMethod agreementMethod) {
2764            return ((AgreementMethodImpl) agreementMethod).toElement();
2765        }
2766
2767        /**
2768         * @param cipherData
2769         * @return
2770         *
2771         */

2772        Element JavaDoc toElement(CipherData cipherData) {
2773            return ((CipherDataImpl) cipherData).toElement();
2774        }
2775
2776        /**
2777         * @param cipherReference
2778         * @return
2779         *
2780         */

2781        Element JavaDoc toElement(CipherReference cipherReference) {
2782            return ((CipherReferenceImpl) cipherReference).toElement();
2783        }
2784
2785        /**
2786         * @param cipherValue
2787         * @return
2788         *
2789         */

2790        Element JavaDoc toElement(CipherValue cipherValue) {
2791            return ((CipherValueImpl) cipherValue).toElement();
2792        }
2793
2794        /**
2795         * @param encryptedData
2796         * @return
2797         *
2798         */

2799        Element JavaDoc toElement(EncryptedData encryptedData) {
2800            return ((EncryptedDataImpl) encryptedData).toElement();
2801        }
2802
2803        /**
2804         * @param encryptedKey
2805         * @return
2806         *
2807         */

2808        Element JavaDoc toElement(EncryptedKey encryptedKey) {
2809            return ((EncryptedKeyImpl) encryptedKey).toElement();
2810        }
2811
2812        /**
2813         * @param encryptionMethod
2814         * @return
2815         *
2816         */

2817        Element JavaDoc toElement(EncryptionMethod encryptionMethod) {
2818            return ((EncryptionMethodImpl) encryptionMethod).toElement();
2819        }
2820
2821        /**
2822         * @param encryptionProperties
2823         * @return
2824         *
2825         */

2826        Element JavaDoc toElement(EncryptionProperties encryptionProperties) {
2827            return ((EncryptionPropertiesImpl) encryptionProperties).toElement();
2828        }
2829
2830        /**
2831         * @param encryptionProperty
2832         * @return
2833         *
2834         */

2835        Element JavaDoc toElement(EncryptionProperty encryptionProperty) {
2836            return ((EncryptionPropertyImpl) encryptionProperty).toElement();
2837        }
2838
2839        Element JavaDoc toElement(ReferenceList referenceList) {
2840            return ((ReferenceListImpl) referenceList).toElement();
2841        }
2842
2843        /**
2844         * @param transforms
2845         * @return
2846         *
2847         */

2848        Element JavaDoc toElement(Transforms transforms) {
2849            return ((TransformsImpl) transforms).toElement();
2850        }
2851
2852        // <element name="AgreementMethod" type="xenc:AgreementMethodType"/>
2853
// <complexType name="AgreementMethodType" mixed="true">
2854
// <sequence>
2855
// <element name="KA-Nonce" minOccurs="0" type="base64Binary"/>
2856
// <!-- <element ref="ds:DigestMethod" minOccurs="0"/> -->
2857
// <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
2858
// <element name="OriginatorKeyInfo" minOccurs="0" type="ds:KeyInfoType"/>
2859
// <element name="RecipientKeyInfo" minOccurs="0" type="ds:KeyInfoType"/>
2860
// </sequence>
2861
// <attribute name="Algorithm" type="anyURI" use="required"/>
2862
// </complexType>
2863
private class AgreementMethodImpl implements AgreementMethod {
2864            private byte[] kaNonce = null;
2865            private List JavaDoc agreementMethodInformation = null;
2866            private KeyInfo originatorKeyInfo = null;
2867            private KeyInfo recipientKeyInfo = null;
2868            private String JavaDoc algorithmURI = null;
2869
2870            /**
2871             * @param algorithm
2872             */

2873            public AgreementMethodImpl(String JavaDoc algorithm) {
2874                agreementMethodInformation = new LinkedList JavaDoc();
2875                URI tmpAlgorithm = null;
2876                try {
2877                    tmpAlgorithm = new URI(algorithm);
2878                } catch (URI.MalformedURIException fmue) {
2879                    //complain?
2880
}
2881                algorithmURI = tmpAlgorithm.toString();
2882            }
2883
2884            /** @inheritDoc */
2885            public byte[] getKANonce() {
2886                return (kaNonce);
2887            }
2888
2889            /** @inheritDoc */
2890            public void setKANonce(byte[] kanonce) {
2891                kaNonce = kanonce;
2892            }
2893
2894            /** @inheritDoc */
2895            public Iterator JavaDoc getAgreementMethodInformation() {
2896                return (agreementMethodInformation.iterator());
2897            }
2898
2899            /** @inheritDoc */
2900            public void addAgreementMethodInformation(Element JavaDoc info) {
2901                agreementMethodInformation.add(info);
2902            }
2903
2904            /** @inheritDoc */
2905            public void revoveAgreementMethodInformation(Element JavaDoc info) {
2906                agreementMethodInformation.remove(info);
2907            }
2908
2909            /** @inheritDoc */
2910            public KeyInfo getOriginatorKeyInfo() {
2911                return (originatorKeyInfo);
2912            }
2913
2914            /** @inheritDoc */
2915            public void setOriginatorKeyInfo(KeyInfo keyInfo) {
2916                originatorKeyInfo = keyInfo;
2917            }
2918
2919            /** @inheritDoc */
2920            public KeyInfo getRecipientKeyInfo() {
2921                return (recipientKeyInfo);
2922            }
2923
2924            /** @inheritDoc */
2925            public void setRecipientKeyInfo(KeyInfo keyInfo) {
2926                recipientKeyInfo = keyInfo;
2927            }
2928
2929            /** @inheritDoc */
2930            public String JavaDoc getAlgorithm() {
2931                return (algorithmURI);
2932            }
2933
2934            /** @param algorithm*/
2935            public void setAlgorithm(String JavaDoc algorithm) {
2936                URI tmpAlgorithm = null;
2937                try {
2938                    tmpAlgorithm = new URI(algorithm);
2939                } catch (URI.MalformedURIException mfue) {
2940                    //complain
2941
}
2942                algorithm = tmpAlgorithm.toString();
2943            }
2944
2945            // <element name="AgreementMethod" type="xenc:AgreementMethodType"/>
2946
// <complexType name="AgreementMethodType" mixed="true">
2947
// <sequence>
2948
// <element name="KA-Nonce" minOccurs="0" type="base64Binary"/>
2949
// <!-- <element ref="ds:DigestMethod" minOccurs="0"/> -->
2950
// <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
2951
// <element name="OriginatorKeyInfo" minOccurs="0" type="ds:KeyInfoType"/>
2952
// <element name="RecipientKeyInfo" minOccurs="0" type="ds:KeyInfoType"/>
2953
// </sequence>
2954
// <attribute name="Algorithm" type="anyURI" use="required"/>
2955
// </complexType>
2956
Element JavaDoc toElement() {
2957                Element JavaDoc result = ElementProxy.createElementForFamily(
2958                    _contextDocument,
2959                    EncryptionConstants.EncryptionSpecNS,
2960                    EncryptionConstants._TAG_AGREEMENTMETHOD);
2961                result.setAttributeNS(
2962                    null, EncryptionConstants._ATT_ALGORITHM, algorithmURI);
2963                if (null != kaNonce) {
2964                    result.appendChild(
2965                        ElementProxy.createElementForFamily(
2966                            _contextDocument,
2967                            EncryptionConstants.EncryptionSpecNS,
2968                            EncryptionConstants._TAG_KA_NONCE)).appendChild(
2969                            _contextDocument.createTextNode(new String JavaDoc(kaNonce)));
2970                }
2971                if (!agreementMethodInformation.isEmpty()) {
2972                    Iterator JavaDoc itr = agreementMethodInformation.iterator();
2973                    while (itr.hasNext()) {
2974                        result.appendChild((Element JavaDoc) itr.next());
2975                    }
2976                }
2977                if (null != originatorKeyInfo) {
2978                    result.appendChild(originatorKeyInfo.getElement());
2979                }
2980                if (null != recipientKeyInfo) {
2981                    result.appendChild(recipientKeyInfo.getElement());
2982                }
2983
2984                return (result);
2985            }
2986        }
2987
2988        // <element name='CipherData' type='xenc:CipherDataType'/>
2989
// <complexType name='CipherDataType'>
2990
// <choice>
2991
// <element name='CipherValue' type='base64Binary'/>
2992
// <element ref='xenc:CipherReference'/>
2993
// </choice>
2994
// </complexType>
2995
private class CipherDataImpl implements CipherData {
2996            private static final String JavaDoc valueMessage =
2997                "Data type is reference type.";
2998            private static final String JavaDoc referenceMessage =
2999                "Data type is value type.";
3000            private CipherValue cipherValue = null;
3001            private CipherReference cipherReference = null;
3002            private int cipherType = Integer.MIN_VALUE;
3003
3004            /**
3005             * @param type
3006             */

3007            public CipherDataImpl(int type) {
3008                cipherType = type;
3009            }
3010
3011            /** @inheritDoc */
3012            public CipherValue getCipherValue() {
3013                return (cipherValue);
3014            }
3015
3016            /** @inheritDoc */
3017            public void setCipherValue(CipherValue value) throws
3018                    XMLEncryptionException {
3019
3020                if (cipherType == REFERENCE_TYPE) {
3021                    throw new XMLEncryptionException("empty",
3022                        new UnsupportedOperationException JavaDoc(valueMessage));
3023                }
3024
3025                cipherValue = value;
3026            }
3027
3028            /** @inheritDoc */
3029            public CipherReference getCipherReference() {
3030                return (cipherReference);
3031            }
3032
3033            /** @inheritDoc */
3034            public void setCipherReference(CipherReference reference) throws
3035                    XMLEncryptionException {
3036                if (cipherType == VALUE_TYPE) {
3037                    throw new XMLEncryptionException("empty",
3038                        new UnsupportedOperationException JavaDoc(referenceMessage));
3039                }
3040
3041                cipherReference = reference;
3042            }
3043
3044            /** @inheritDoc */
3045            public int getDataType() {
3046                return (cipherType);
3047            }
3048
3049            // <element name='CipherData' type='xenc:CipherDataType'/>
3050
// <complexType name='CipherDataType'>
3051
// <choice>
3052
// <element name='CipherValue' type='base64Binary'/>
3053
// <element ref='xenc:CipherReference'/>
3054
// </choice>
3055
// </complexType>
3056
Element JavaDoc toElement() {
3057                Element JavaDoc result = ElementProxy.createElementForFamily(
3058                    _contextDocument,
3059                    EncryptionConstants.EncryptionSpecNS,
3060                    EncryptionConstants._TAG_CIPHERDATA);
3061                if (cipherType == VALUE_TYPE) {
3062                    result.appendChild(
3063                        ((CipherValueImpl) cipherValue).toElement());
3064                } else if (cipherType == REFERENCE_TYPE) {
3065                    result.appendChild(
3066                        ((CipherReferenceImpl) cipherReference).toElement());
3067                } else {
3068                    // complain
3069
}
3070
3071                return (result);
3072            }
3073        }
3074
3075        // <element name='CipherReference' type='xenc:CipherReferenceType'/>
3076
// <complexType name='CipherReferenceType'>
3077
// <sequence>
3078
// <element name='Transforms' type='xenc:TransformsType' minOccurs='0'/>
3079
// </sequence>
3080
// <attribute name='URI' type='anyURI' use='required'/>
3081
// </complexType>
3082
private class CipherReferenceImpl implements CipherReference {
3083            private String JavaDoc referenceURI = null;
3084            private Transforms referenceTransforms = null;
3085            private Attr JavaDoc referenceNode = null;
3086
3087            /**
3088             * @param uri
3089             */

3090            public CipherReferenceImpl(String JavaDoc uri) {
3091                /* Don't check validity of URI as may be "" */
3092                referenceURI = uri;
3093                referenceNode = null;
3094            }
3095
3096            /**
3097             * @param uri
3098             */

3099            public CipherReferenceImpl(Attr JavaDoc uri) {
3100                referenceURI = uri.getNodeValue();
3101                referenceNode = uri;
3102            }
3103
3104            /** @inheritDoc */
3105            public String JavaDoc getURI() {
3106                return (referenceURI);
3107            }
3108
3109            /** @inheritDoc */
3110            public Attr JavaDoc getURIAsAttr() {
3111                return (referenceNode);
3112            }
3113
3114            /** @inheritDoc */
3115            public Transforms getTransforms() {
3116                return (referenceTransforms);
3117            }
3118
3119            /** @inheritDoc */
3120            public void setTransforms(Transforms transforms) {
3121                referenceTransforms = transforms;
3122            }
3123
3124            // <element name='CipherReference' type='xenc:CipherReferenceType'/>
3125
// <complexType name='CipherReferenceType'>
3126
// <sequence>
3127
// <element name='Transforms' type='xenc:TransformsType' minOccurs='0'/>
3128
// </sequence>
3129
// <attribute name='URI' type='anyURI' use='required'/>
3130
// </complexType>
3131
Element JavaDoc toElement() {
3132                Element JavaDoc result = ElementProxy.createElementForFamily(
3133                    _contextDocument,
3134                    EncryptionConstants.EncryptionSpecNS,
3135                    EncryptionConstants._TAG_CIPHERREFERENCE);
3136                result.setAttributeNS(
3137                    null, EncryptionConstants._ATT_URI, referenceURI);
3138                if (null != referenceTransforms) {
3139                    result.appendChild(
3140                        ((TransformsImpl) referenceTransforms).toElement());
3141                }
3142
3143                return (result);
3144            }
3145        }
3146
3147        private class CipherValueImpl implements CipherValue {
3148            private String JavaDoc cipherValue = null;
3149            
3150            // public CipherValueImpl(byte[] value) {
3151
// cipherValue = value;
3152
// }
3153

3154            /**
3155             * @param value
3156             */

3157            public CipherValueImpl(String JavaDoc value) {
3158                // cipherValue = value.getBytes();
3159
cipherValue = value;
3160            }
3161
3162            /** @inheritDoc */
3163            public String JavaDoc getValue() {
3164                return (cipherValue);
3165            }
3166
3167            // public void setValue(byte[] value) {
3168
// public void setValue(String value) {
3169
// cipherValue = value;
3170
// }
3171
/** @inheritDoc */
3172            public void setValue(String JavaDoc value) {
3173                // cipherValue = value.getBytes();
3174
cipherValue = value;
3175            }
3176
3177            Element JavaDoc toElement() {
3178                Element JavaDoc result = ElementProxy.createElementForFamily(
3179                    _contextDocument, EncryptionConstants.EncryptionSpecNS,
3180                    EncryptionConstants._TAG_CIPHERVALUE);
3181                result.appendChild(_contextDocument.createTextNode(
3182                    new String JavaDoc(cipherValue)));
3183
3184                return (result);
3185            }
3186        }
3187
3188        // <complexType name='EncryptedType' abstract='true'>
3189
// <sequence>
3190
// <element name='EncryptionMethod' type='xenc:EncryptionMethodType'
3191
// minOccurs='0'/>
3192
// <element ref='ds:KeyInfo' minOccurs='0'/>
3193
// <element ref='xenc:CipherData'/>
3194
// <element ref='xenc:EncryptionProperties' minOccurs='0'/>
3195
// </sequence>
3196
// <attribute name='Id' type='ID' use='optional'/>
3197
// <attribute name='Type' type='anyURI' use='optional'/>
3198
// <attribute name='MimeType' type='string' use='optional'/>
3199
// <attribute name='Encoding' type='anyURI' use='optional'/>
3200
// </complexType>
3201
// <element name='EncryptedData' type='xenc:EncryptedDataType'/>
3202
// <complexType name='EncryptedDataType'>
3203
// <complexContent>
3204
// <extension base='xenc:EncryptedType'/>
3205
// </complexContent>
3206
// </complexType>
3207
private class EncryptedDataImpl extends EncryptedTypeImpl implements
3208                EncryptedData {
3209            /**
3210             * @param data
3211             */

3212            public EncryptedDataImpl(CipherData data) {
3213                super(data);
3214            }
3215
3216            // <complexType name='EncryptedType' abstract='true'>
3217
// <sequence>
3218
// <element name='EncryptionMethod' type='xenc:EncryptionMethodType'
3219
// minOccurs='0'/>
3220
// <element ref='ds:KeyInfo' minOccurs='0'/>
3221
// <element ref='xenc:CipherData'/>
3222
// <element ref='xenc:EncryptionProperties' minOccurs='0'/>
3223
// </sequence>
3224
// <attribute name='Id' type='ID' use='optional'/>
3225
// <attribute name='Type' type='anyURI' use='optional'/>
3226
// <attribute name='MimeType' type='string' use='optional'/>
3227
// <attribute name='Encoding' type='anyURI' use='optional'/>
3228
// </complexType>
3229
// <element name='EncryptedData' type='xenc:EncryptedDataType'/>
3230
// <complexType name='EncryptedDataType'>
3231
// <complexContent>
3232
// <extension base='xenc:EncryptedType'/>
3233
// </complexContent>
3234
// </complexType>
3235
Element JavaDoc toElement() {
3236                Element JavaDoc result = ElementProxy.createElementForFamily(
3237                    _contextDocument, EncryptionConstants.EncryptionSpecNS,
3238                    EncryptionConstants._TAG_ENCRYPTEDDATA);
3239
3240                if (null != super.getId()) {
3241                    result.setAttributeNS(
3242                        null, EncryptionConstants._ATT_ID, super.getId());
3243                }
3244                if (null != super.getType()) {
3245                    result.setAttributeNS(
3246                        null, EncryptionConstants._ATT_TYPE,
3247                        super.getType().toString());
3248                }
3249                if (null != super.getMimeType()) {
3250                    result.setAttributeNS(
3251                        null, EncryptionConstants._ATT_MIMETYPE,
3252                        super.getMimeType());
3253                }
3254                if (null != super.getEncoding()) {
3255                    result.setAttributeNS(
3256                        null, EncryptionConstants._ATT_ENCODING,
3257                        super.getEncoding().toString());
3258                }
3259                if (null != super.getEncryptionMethod()) {
3260                    result.appendChild(((EncryptionMethodImpl)
3261                        super.getEncryptionMethod()).toElement());
3262                }
3263                if (null != super.getKeyInfo()) {
3264                    result.appendChild(super.getKeyInfo().getElement());
3265                }
3266
3267                result.appendChild(
3268                    ((CipherDataImpl) super.getCipherData()).toElement());
3269                if (null != super.getEncryptionProperties()) {
3270                    result.appendChild(((EncryptionPropertiesImpl)
3271                        super.getEncryptionProperties()).toElement());
3272                }
3273
3274                return (result);
3275            }
3276        }
3277
3278        // <complexType name='EncryptedType' abstract='true'>
3279
// <sequence>
3280
// <element name='EncryptionMethod' type='xenc:EncryptionMethodType'
3281
// minOccurs='0'/>
3282
// <element ref='ds:KeyInfo' minOccurs='0'/>
3283
// <element ref='xenc:CipherData'/>
3284
// <element ref='xenc:EncryptionProperties' minOccurs='0'/>
3285
// </sequence>
3286
// <attribute name='Id' type='ID' use='optional'/>
3287
// <attribute name='Type' type='anyURI' use='optional'/>
3288
// <attribute name='MimeType' type='string' use='optional'/>
3289
// <attribute name='Encoding' type='anyURI' use='optional'/>
3290
// </complexType>
3291
// <element name='EncryptedKey' type='xenc:EncryptedKeyType'/>
3292
// <complexType name='EncryptedKeyType'>
3293
// <complexContent>
3294
// <extension base='xenc:EncryptedType'>
3295
// <sequence>
3296
// <element ref='xenc:ReferenceList' minOccurs='0'/>
3297
// <element name='CarriedKeyName' type='string' minOccurs='0'/>
3298
// </sequence>
3299
// <attribute name='Recipient' type='string' use='optional'/>
3300
// </extension>
3301
// </complexContent>
3302
// </complexType>
3303
private class EncryptedKeyImpl extends EncryptedTypeImpl implements
3304                EncryptedKey {
3305            private String JavaDoc keyRecipient = null;
3306            private ReferenceList referenceList = null;
3307            private String JavaDoc carriedName = null;
3308
3309            /**
3310             * @param data
3311             */

3312            public EncryptedKeyImpl(CipherData data) {
3313                super(data);
3314            }
3315
3316            /** @inheritDoc */
3317            public String JavaDoc getRecipient() {
3318                return (keyRecipient);
3319            }
3320
3321            /** @inheritDoc */
3322            public void setRecipient(String JavaDoc recipient) {
3323                keyRecipient = recipient;
3324            }
3325
3326            /** @inheritDoc */
3327            public ReferenceList getReferenceList() {
3328                return (referenceList);
3329            }
3330
3331            /** @inheritDoc */
3332            public void setReferenceList(ReferenceList list) {
3333                referenceList = list;
3334            }
3335
3336            /** @inheritDoc */
3337            public String JavaDoc getCarriedName() {
3338                return (carriedName);
3339            }
3340
3341            /** @inheritDoc */
3342            public void setCarriedName(String JavaDoc name) {
3343                carriedName = name;
3344            }
3345
3346            // <complexType name='EncryptedType' abstract='true'>
3347
// <sequence>
3348
// <element name='EncryptionMethod' type='xenc:EncryptionMethodType'
3349
// minOccurs='0'/>
3350
// <element ref='ds:KeyInfo' minOccurs='0'/>
3351
// <element ref='xenc:CipherData'/>
3352
// <element ref='xenc:EncryptionProperties' minOccurs='0'/>
3353
// </sequence>
3354
// <attribute name='Id' type='ID' use='optional'/>
3355
// <attribute name='Type' type='anyURI' use='optional'/>
3356
// <attribute name='MimeType' type='string' use='optional'/>
3357
// <attribute name='Encoding' type='anyURI' use='optional'/>
3358
// </complexType>
3359
// <element name='EncryptedKey' type='xenc:EncryptedKeyType'/>
3360
// <complexType name='EncryptedKeyType'>
3361
// <complexContent>
3362
// <extension base='xenc:EncryptedType'>
3363
// <sequence>
3364
// <element ref='xenc:ReferenceList' minOccurs='0'/>
3365
// <element name='CarriedKeyName' type='string' minOccurs='0'/>
3366
// </sequence>
3367
// <attribute name='Recipient' type='string' use='optional'/>
3368
// </extension>
3369
// </complexContent>
3370
// </complexType>
3371
Element JavaDoc toElement() {
3372                Element JavaDoc result = ElementProxy.createElementForFamily(
3373                    _contextDocument, EncryptionConstants.EncryptionSpecNS,
3374                    EncryptionConstants._TAG_ENCRYPTEDKEY);
3375
3376                if (null != super.getId()) {
3377                    result.setAttributeNS(
3378                        null, EncryptionConstants._ATT_ID, super.getId());
3379                }
3380                if (null != super.getType()) {
3381                    result.setAttributeNS(
3382                        null, EncryptionConstants._ATT_TYPE,
3383                        super.getType().toString());
3384                }
3385                if (null != super.getMimeType()) {
3386                    result.setAttributeNS(null,
3387                        EncryptionConstants._ATT_MIMETYPE, super.getMimeType());
3388                }
3389                if (null != super.getEncoding()) {
3390                    result.setAttributeNS(null, Constants._ATT_ENCODING,
3391                        super.getEncoding().toString());
3392                }
3393                if (null != getRecipient()) {
3394                    result.setAttributeNS(null,
3395                        EncryptionConstants._ATT_RECIPIENT, getRecipient());
3396                }
3397                if (null != super.getEncryptionMethod()) {
3398                    result.appendChild(((EncryptionMethodImpl)
3399                        super.getEncryptionMethod()).toElement());
3400                }
3401                if (null != super.getKeyInfo()) {
3402                    result.appendChild(super.getKeyInfo().getElement());
3403                }
3404                result.appendChild(
3405                    ((CipherDataImpl) super.getCipherData()).toElement());
3406                if (null != super.getEncryptionProperties()) {
3407                    result.appendChild(((EncryptionPropertiesImpl)
3408                        super.getEncryptionProperties()).toElement());
3409                }
3410                if (referenceList != null && !referenceList.isEmpty()) {
3411                    result.appendChild(((ReferenceListImpl)
3412                        getReferenceList()).toElement());
3413                }
3414                if (null != carriedName) {
3415                    Element JavaDoc element = ElementProxy.createElementForFamily(
3416            _contextDocument,
3417                        EncryptionConstants.EncryptionSpecNS,
3418                        EncryptionConstants._TAG_CARRIEDKEYNAME);
3419                    Node JavaDoc node = _contextDocument.createTextNode(carriedName);
3420                    element.appendChild(node);
3421                    result.appendChild(element);
3422                }
3423
3424                return (result);
3425            }
3426        }
3427
3428        private abstract class EncryptedTypeImpl {
3429            private String JavaDoc id = null;
3430            private String JavaDoc type = null;
3431            private String JavaDoc mimeType = null;
3432            private String JavaDoc encoding = null;
3433            private EncryptionMethod encryptionMethod = null;
3434            private KeyInfo keyInfo = null;
3435            private CipherData cipherData = null;
3436            private EncryptionProperties encryptionProperties = null;
3437
3438            protected EncryptedTypeImpl(CipherData data) {
3439                cipherData = data;
3440            }
3441            /**
3442             *
3443             * @return
3444             */

3445            public String JavaDoc getId() {
3446                return (id);
3447            }
3448            /**
3449             *
3450             * @param id
3451             */

3452            public void setId(String JavaDoc id) {
3453                this.id = id;
3454            }
3455            /**
3456             *
3457             * @return
3458             */

3459            public String JavaDoc getType() {
3460                return (type);
3461            }
3462            /**
3463             *
3464             * @param type
3465             */

3466            public void setType(String JavaDoc type) {
3467                URI tmpType = null;
3468                try {
3469                    tmpType = new URI(type);
3470                } catch (URI.MalformedURIException mfue) {
3471                    // complain
3472
}
3473                this.type = tmpType.toString();
3474            }
3475            /**
3476             *
3477             * @return
3478             */

3479            public String JavaDoc getMimeType() {
3480                return (mimeType);
3481            }
3482            /**
3483             *
3484             * @param type
3485             */

3486            public void setMimeType(String JavaDoc type) {
3487                mimeType = type;
3488            }
3489            /**
3490             *
3491             * @return
3492             */

3493            public String JavaDoc getEncoding() {
3494                return (encoding);
3495            }
3496            /**
3497             *
3498             * @param encoding
3499             */

3500            public void setEncoding(String JavaDoc encoding) {
3501                URI tmpEncoding = null;
3502                try {
3503                    tmpEncoding = new URI(encoding);
3504                } catch (URI.MalformedURIException mfue) {
3505                    // complain
3506
}
3507                this.encoding = tmpEncoding.toString();
3508            }
3509            /**
3510             *
3511             * @return
3512             */

3513            public EncryptionMethod getEncryptionMethod() {
3514                return (encryptionMethod);
3515            }
3516            /**
3517             *
3518             * @param method
3519             */

3520            public void setEncryptionMethod(EncryptionMethod method) {
3521                encryptionMethod = method;
3522            }
3523            /**
3524             *
3525             * @return
3526             */

3527            public KeyInfo getKeyInfo() {
3528                return (keyInfo);
3529            }
3530            /**
3531             *
3532             * @param info
3533             */

3534            public void setKeyInfo(KeyInfo info) {
3535                keyInfo = info;
3536            }
3537            /**
3538             *
3539             * @return
3540             */

3541            public CipherData getCipherData() {
3542                return (cipherData);
3543            }
3544            /**
3545             *
3546             * @return
3547             */

3548            public EncryptionProperties getEncryptionProperties() {
3549                return (encryptionProperties);
3550            }
3551            /**
3552             *
3553             * @param properties
3554             */

3555            public void setEncryptionProperties(
3556                    EncryptionProperties properties) {
3557                encryptionProperties = properties;
3558            }
3559        }
3560
3561        // <complexType name='EncryptionMethodType' mixed='true'>
3562
// <sequence>
3563
// <element name='KeySize' minOccurs='0' type='xenc:KeySizeType'/>
3564
// <element name='OAEPparams' minOccurs='0' type='base64Binary'/>
3565
// <any namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
3566
// </sequence>
3567
// <attribute name='Algorithm' type='anyURI' use='required'/>
3568
// </complexType>
3569
private class EncryptionMethodImpl implements EncryptionMethod {
3570            private String JavaDoc algorithm = null;
3571            private int keySize = Integer.MIN_VALUE;
3572            private byte[] oaepParams = null;
3573            private List JavaDoc encryptionMethodInformation = null;
3574            /**
3575             *
3576             * @param algorithm
3577             */

3578            public EncryptionMethodImpl(String JavaDoc algorithm) {
3579                URI tmpAlgorithm = null;
3580                try {
3581                    tmpAlgorithm = new URI(algorithm);
3582                } catch (URI.MalformedURIException mfue) {
3583                    // complain
3584
}
3585                this.algorithm = tmpAlgorithm.toString();
3586                encryptionMethodInformation = new LinkedList JavaDoc();
3587            }
3588            /** @inheritDoc */
3589            public String JavaDoc getAlgorithm() {
3590                return (algorithm);
3591            }
3592            /** @inheritDoc */
3593            public int getKeySize() {
3594                return (keySize);
3595            }
3596            /** @inheritDoc */
3597            public void setKeySize(int size) {
3598                keySize = size;
3599            }
3600            /** @inheritDoc */
3601            public byte[] getOAEPparams() {
3602                return (oaepParams);
3603            }
3604            /** @inheritDoc */
3605            public void setOAEPparams(byte[] params) {
3606                oaepParams = params;
3607            }
3608            /** @inheritDoc */
3609            public Iterator JavaDoc getEncryptionMethodInformation() {
3610                return (encryptionMethodInformation.iterator());
3611            }
3612            /** @inheritDoc */
3613            public void addEncryptionMethodInformation(Element JavaDoc info) {
3614                encryptionMethodInformation.add(info);
3615            }
3616            /** @inheritDoc */
3617            public void removeEncryptionMethodInformation(Element JavaDoc info) {
3618                encryptionMethodInformation.remove(info);
3619            }
3620
3621            // <complexType name='EncryptionMethodType' mixed='true'>
3622
// <sequence>
3623
// <element name='KeySize' minOccurs='0' type='xenc:KeySizeType'/>
3624
// <element name='OAEPparams' minOccurs='0' type='base64Binary'/>
3625
// <any namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
3626
// </sequence>
3627
// <attribute name='Algorithm' type='anyURI' use='required'/>
3628
// </complexType>
3629
Element JavaDoc toElement() {
3630                Element JavaDoc result = ElementProxy.createElementForFamily(
3631                    _contextDocument, EncryptionConstants.EncryptionSpecNS,
3632                    EncryptionConstants._TAG_ENCRYPTIONMETHOD);
3633                result.setAttributeNS(null, EncryptionConstants._ATT_ALGORITHM,
3634                    algorithm.toString());
3635                if (keySize > 0) {
3636                    result.appendChild(
3637                        ElementProxy.createElementForFamily(_contextDocument,
3638                            EncryptionConstants.EncryptionSpecNS,
3639                            EncryptionConstants._TAG_KEYSIZE).appendChild(
3640                            _contextDocument.createTextNode(
3641                                String.valueOf(keySize))));
3642                }
3643                if (null != oaepParams) {
3644                    result.appendChild(
3645                        ElementProxy.createElementForFamily(_contextDocument,
3646                            EncryptionConstants.EncryptionSpecNS,
3647                            EncryptionConstants._TAG_OAEPPARAMS).appendChild(
3648                            _contextDocument.createTextNode(
3649                                new String JavaDoc(oaepParams))));
3650                }
3651                if (!encryptionMethodInformation.isEmpty()) {
3652                    Iterator JavaDoc itr = encryptionMethodInformation.iterator();
3653                    result.appendChild((Element JavaDoc) itr.next());
3654                }
3655
3656                return (result);
3657            }
3658        }
3659
3660        // <element name='EncryptionProperties' type='xenc:EncryptionPropertiesType'/>
3661
// <complexType name='EncryptionPropertiesType'>
3662
// <sequence>
3663
// <element ref='xenc:EncryptionProperty' maxOccurs='unbounded'/>
3664
// </sequence>
3665
// <attribute name='Id' type='ID' use='optional'/>
3666
// </complexType>
3667
private class EncryptionPropertiesImpl implements EncryptionProperties {
3668            private String JavaDoc id = null;
3669            private List JavaDoc encryptionProperties = null;
3670            /**
3671             *
3672             *
3673             */

3674            public EncryptionPropertiesImpl() {
3675                encryptionProperties = new LinkedList JavaDoc();
3676            }
3677            /** @inheritDoc */
3678            public String JavaDoc getId() {
3679                return (id);
3680            }
3681            /** @inheritDoc */
3682            public void setId(String JavaDoc id) {
3683                this.id = id;
3684            }
3685            /** @inheritDoc */
3686            public Iterator JavaDoc getEncryptionProperties() {
3687                return (encryptionProperties.iterator());
3688            }
3689            /** @inheritDoc */
3690            public void addEncryptionProperty(EncryptionProperty property) {
3691                encryptionProperties.add(property);
3692            }
3693            /** @inheritDoc */
3694            public void removeEncryptionProperty(EncryptionProperty property) {
3695                encryptionProperties.remove(property);
3696            }
3697
3698            // <element name='EncryptionProperties' type='xenc:EncryptionPropertiesType'/>
3699
// <complexType name='EncryptionPropertiesType'>
3700
// <sequence>
3701
// <element ref='xenc:EncryptionProperty' maxOccurs='unbounded'/>
3702
// </sequence>
3703
// <attribute name='Id' type='ID' use='optional'/>
3704
// </complexType>
3705
Element JavaDoc toElement() {
3706                Element JavaDoc result = ElementProxy.createElementForFamily(
3707                    _contextDocument, EncryptionConstants.EncryptionSpecNS,
3708                    EncryptionConstants._TAG_ENCRYPTIONPROPERTIES);
3709                if (null != id) {
3710                    result.setAttributeNS(null, EncryptionConstants._ATT_ID, id);
3711                }
3712                Iterator JavaDoc itr = getEncryptionProperties();
3713                while (itr.hasNext()) {
3714                    result.appendChild(((EncryptionPropertyImpl)
3715                        itr.next()).toElement());
3716                }
3717
3718                return (result);
3719            }
3720        }
3721
3722        // <element name='EncryptionProperty' type='xenc:EncryptionPropertyType'/>
3723
// <complexType name='EncryptionPropertyType' mixed='true'>
3724
// <choice maxOccurs='unbounded'>
3725
// <any namespace='##other' processContents='lax'/>
3726
// </choice>
3727
// <attribute name='Target' type='anyURI' use='optional'/>
3728
// <attribute name='Id' type='ID' use='optional'/>
3729
// <anyAttribute namespace="http://www.w3.org/XML/1998/namespace"/>
3730
// </complexType>
3731
private class EncryptionPropertyImpl implements EncryptionProperty {
3732            private String JavaDoc target = null;
3733            private String JavaDoc id = null;
3734            private String JavaDoc attributeName = null;
3735            private String JavaDoc attributeValue = null;
3736            private List JavaDoc encryptionInformation = null;
3737
3738            /**
3739             *
3740             *
3741             */

3742            public EncryptionPropertyImpl() {
3743                encryptionInformation = new LinkedList JavaDoc();
3744            }
3745            /** @inheritDoc */
3746            public String JavaDoc getTarget() {
3747                return (target);
3748            }
3749            /** @inheritDoc */
3750            public void setTarget(String JavaDoc target) {
3751                URI tmpTarget = null;
3752                try {
3753                    tmpTarget = new URI(target);
3754                } catch (URI.MalformedURIException mfue) {
3755                    // complain
3756
}
3757                this.target = tmpTarget.toString();
3758            }
3759            /** @inheritDoc */
3760            public String JavaDoc getId() {
3761                return (id);
3762            }
3763            /** @inheritDoc */
3764            public void setId(String JavaDoc id) {
3765                this.id = id;
3766            }
3767            /** @inheritDoc */
3768            public String JavaDoc getAttribute(String JavaDoc attribute) {
3769                return (attributeValue);
3770            }
3771            /** @inheritDoc */
3772            public void setAttribute(String JavaDoc attribute, String JavaDoc value) {
3773                attributeName = attribute;
3774                attributeValue = value;
3775            }
3776            /** @inheritDoc */
3777            public Iterator JavaDoc getEncryptionInformation() {
3778                return (encryptionInformation.iterator());
3779            }
3780            /** @inheritDoc */
3781            public void addEncryptionInformation(Element JavaDoc info) {
3782                encryptionInformation.add(info);
3783            }
3784            /** @inheritDoc */
3785            public void removeEncryptionInformation(Element JavaDoc info) {
3786                encryptionInformation.remove(info);
3787            }
3788
3789            // <element name='EncryptionProperty' type='xenc:EncryptionPropertyType'/>
3790
// <complexType name='EncryptionPropertyType' mixed='true'>
3791
// <choice maxOccurs='unbounded'>
3792
// <any namespace='##other' processContents='lax'/>
3793
// </choice>
3794
// <attribute name='Target' type='anyURI' use='optional'/>
3795
// <attribute name='Id' type='ID' use='optional'/>
3796
// <anyAttribute namespace="http://www.w3.org/XML/1998/namespace"/>
3797
// </complexType>
3798
Element JavaDoc toElement() {
3799                Element JavaDoc result = ElementProxy.createElementForFamily(
3800                    _contextDocument, EncryptionConstants.EncryptionSpecNS,
3801                    EncryptionConstants._TAG_ENCRYPTIONPROPERTY);
3802                if (null != target) {
3803                    result.setAttributeNS(null, EncryptionConstants._ATT_TARGET,
3804                        target.toString());
3805                }
3806                if (null != id) {
3807                    result.setAttributeNS(null, EncryptionConstants._ATT_ID,
3808                        id);
3809                }
3810                // TODO: figure out the anyAttribyte stuff...
3811
// TODO: figure out the any stuff...
3812

3813                return (result);
3814            }
3815        }
3816
3817        // <complexType name='TransformsType'>
3818
// <sequence>
3819
// <element ref='ds:Transform' maxOccurs='unbounded'/>
3820
// </sequence>
3821
// </complexType>
3822
private class TransformsImpl extends
3823               com.sun.org.apache.xml.internal.security.transforms.Transforms
3824               implements Transforms {
3825
3826            /**
3827             * Construct Transforms
3828             */

3829
3830            public TransformsImpl() {
3831                super(_contextDocument);
3832            }
3833            /**
3834             *
3835             * @param doc
3836             */

3837            public TransformsImpl(Document JavaDoc doc) {
3838                super(doc);
3839            }
3840            /**
3841             *
3842             * @param element
3843             * @throws XMLSignatureException
3844             * @throws InvalidTransformException
3845             * @throws XMLSecurityException
3846             * @throws TransformationException
3847             */

3848            public TransformsImpl(Element JavaDoc element)
3849                throws XMLSignatureException,
3850                       InvalidTransformException,
3851                       XMLSecurityException,
3852                       TransformationException {
3853
3854                super(element, "");
3855                
3856            }
3857
3858            /**
3859             *
3860             * @return
3861             */

3862            public Element JavaDoc toElement() {
3863
3864                if (_doc == null)
3865                    _doc = _contextDocument;
3866
3867                return getElement();
3868            }
3869
3870            /** @inheritDoc */
3871            public com.sun.org.apache.xml.internal.security.transforms.Transforms getDSTransforms() {
3872                return (this);
3873            }
3874
3875
3876            // Over-ride the namespace
3877
/** @inheritDoc */
3878            public String JavaDoc getBaseNamespace() {
3879                return EncryptionConstants.EncryptionSpecNS;
3880            }
3881
3882        }
3883
3884        //<element name='ReferenceList'>
3885
// <complexType>
3886
// <choice minOccurs='1' maxOccurs='unbounded'>
3887
// <element name='DataReference' type='xenc:ReferenceType'/>
3888
// <element name='KeyReference' type='xenc:ReferenceType'/>
3889
// </choice>
3890
// </complexType>
3891
//</element>
3892
private class ReferenceListImpl implements ReferenceList {
3893            private Class JavaDoc sentry;
3894            private List JavaDoc references;
3895            /**
3896             *
3897             * @param type
3898             */

3899            public ReferenceListImpl(int type) {
3900                if (type == ReferenceList.DATA_REFERENCE) {
3901                    sentry = DataReference.class;
3902                } else if (type == ReferenceList.KEY_REFERENCE) {
3903                    sentry = KeyReference.class;
3904                } else {
3905                    throw new IllegalArgumentException JavaDoc();
3906                }
3907                references = new LinkedList JavaDoc();
3908            }
3909            /** @inheritDoc */
3910            public void add(Reference reference) {
3911                if (!reference.getClass().equals(sentry)) {
3912                    throw new IllegalArgumentException JavaDoc();
3913                }
3914                 references.add(reference);
3915            }
3916            /** @inheritDoc */
3917            public void remove(Reference reference) {
3918                if (!reference.getClass().equals(sentry)) {
3919                    throw new IllegalArgumentException JavaDoc();
3920                }
3921                references.remove(reference);
3922            }
3923            /** @inheritDoc */
3924            public int size() {
3925                return (references.size());
3926            }
3927            /** @inheritDoc */
3928            public boolean isEmpty() {
3929                return (references.isEmpty());
3930            }
3931            /** @inheritDoc */
3932            public Iterator JavaDoc getReferences() {
3933                return (references.iterator());
3934            }
3935
3936            Element JavaDoc toElement() {
3937                Element JavaDoc result = ElementProxy.createElementForFamily(
3938                    _contextDocument,
3939                    EncryptionConstants.EncryptionSpecNS,
3940                    EncryptionConstants._TAG_REFERENCELIST);
3941                Iterator JavaDoc eachReference = references.iterator();
3942                while (eachReference.hasNext()) {
3943                    Reference reference = (Reference) eachReference.next();
3944                    result.appendChild(
3945                        ((ReferenceImpl) reference).toElement());
3946                }
3947                return (result);
3948            }
3949            /** @inheritDoc */
3950            public Reference newDataReference(String JavaDoc uri) {
3951                return (new DataReference(uri));
3952            }
3953            /** @inheritDoc */
3954            public Reference newKeyReference(String JavaDoc uri) {
3955                return (new KeyReference(uri));
3956            }
3957
3958            /**
3959             * <code>ReferenceImpl</code> is an implementation of
3960             * <code>Reference</code>.
3961             *
3962             * @see Reference
3963             */

3964            private abstract class ReferenceImpl implements Reference {
3965                private String JavaDoc uri;
3966                private List JavaDoc referenceInformation;
3967
3968                ReferenceImpl(String JavaDoc _uri) {
3969                    this.uri = _uri;
3970                    referenceInformation = new LinkedList JavaDoc();
3971                }
3972                /** @inheritDoc */
3973                public String JavaDoc getURI() {
3974                    return (uri);
3975                }
3976                /** @inheritDoc */
3977                public Iterator JavaDoc getElementRetrievalInformation() {
3978                    return (referenceInformation.iterator());
3979                }
3980                /** @inheritDoc */
3981                public void setURI(String JavaDoc _uri) {
3982                    this.uri = _uri;
3983                }
3984                /** @inheritDoc */
3985                public void removeElementRetrievalInformation(Element JavaDoc node) {
3986                    referenceInformation.remove(node);
3987                }
3988                /** @inheritDoc */
3989                public void addElementRetrievalInformation(Element JavaDoc node) {
3990                    referenceInformation.add(node);
3991                }
3992                /**
3993                 *
3994                 * @return
3995                 */

3996                public abstract Element JavaDoc toElement();
3997
3998                Element JavaDoc toElement(String JavaDoc tagName) {
3999                    Element JavaDoc result = ElementProxy.createElementForFamily(
4000                        _contextDocument,
4001                        EncryptionConstants.EncryptionSpecNS,
4002                        tagName);
4003                    result.setAttribute(EncryptionConstants._ATT_URI, uri);
4004
4005                    // TODO: Need to martial referenceInformation
4006
// Figure out how to make this work..
4007
// <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
4008

4009                    return (result);
4010                }
4011            }
4012
4013            private class DataReference extends ReferenceImpl {
4014                DataReference(String JavaDoc uri) {
4015                    super(uri);
4016                }
4017                /** @inheritDoc */
4018                public Element JavaDoc toElement() {
4019                    return super.toElement(EncryptionConstants._TAG_DATAREFERENCE);
4020                }
4021            }
4022
4023            private class KeyReference extends ReferenceImpl {
4024                KeyReference(String JavaDoc uri) {
4025                    super (uri);
4026                }
4027                /** @inheritDoc */
4028                public Element JavaDoc toElement() {
4029                    return super.toElement(EncryptionConstants._TAG_KEYREFERENCE);
4030                }
4031            }
4032        }
4033    }
4034}
4035
Popular Tags