1 /*
2  * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 /*
26  * $Id: XMLSignatureFactory.java,v 1.14 2005/09/15 14:29:01 mullan Exp $
27  */
28 package javax.xml.crypto.dsig;
29 
30 import javax.xml.crypto.Data;
31 import javax.xml.crypto.MarshalException;
32 import javax.xml.crypto.NoSuchMechanismException;
33 import javax.xml.crypto.URIDereferencer;
34 import javax.xml.crypto.XMLStructure;
35 import javax.xml.crypto.dom.DOMStructure;
36 import javax.xml.crypto.dsig.keyinfo.KeyInfo;
37 import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
38 import javax.xml.crypto.dsig.spec.*;
39 import javax.xml.crypto.dsig.dom.DOMValidateContext;
40 import javax.xml.crypto.dsig.dom.DOMSignContext;
41 
42 import java.security.InvalidAlgorithmParameterException;
43 import java.security.NoSuchAlgorithmException;
44 import java.security.NoSuchProviderException;
45 import java.security.Provider;
46 import java.security.Provider.Service;
47 import java.security.Security;
48 import java.util.List;
49 
50 
51 /**
52  * A factory for creating {@link XMLSignature} objects from scratch or
53  * for unmarshalling an <code>XMLSignature</code> object from a corresponding
54  * XML representation.
55  *
56  * <h2>XMLSignatureFactory Type</h2>
57  *
58  * <p>Each instance of <code>XMLSignatureFactory</code> supports a specific
59  * XML mechanism type. To create an <code>XMLSignatureFactory</code>, call one
60  * of the static {@link #getInstance getInstance} methods, passing in the XML
61  * mechanism type desired, for example:
62  *
63  * <blockquote><code>
64  * XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM");
65  * </code></blockquote>
66  *
67  * <p>The objects that this factory produces will be based
68  * on DOM and abide by the DOM interoperability requirements as defined in the
69  * <a href="package-summary.html#dom_req">DOM Mechanism Requirements</a>.
70  * See the {@code XMLSignatureFactory} section in the <a href=
71  * "{@docRoot}/../specs/security/standard-names.html#xml-signature-xmlsignaturefactorykeyinfofactorytransformservice-mechanisms">
72  * Java Security Standard Algorithm Names Specification</a> for a list of
73  * standard mechanism types.
74  *
75  * <p><code>XMLSignatureFactory</code> implementations are registered and loaded
76  * using the {@link java.security.Provider} mechanism.
77  * For example, a service provider that supports the
78  * DOM mechanism would be specified in the <code>Provider</code> subclass as:
79  * <pre>
80  *     put("XMLSignatureFactory.DOM", "org.example.DOMXMLSignatureFactory");
81  * </pre>
82  *
83  * <p>An implementation MUST minimally support the default mechanism type: DOM.
84  *
85  * <p>Note that a caller must use the same <code>XMLSignatureFactory</code>
86  * instance to create the <code>XMLStructure</code>s of a particular
87  * <code>XMLSignature</code> that is to be generated. The behavior is
88  * undefined if <code>XMLStructure</code>s from different providers or
89  * different mechanism types are used together.
90  *
91  * <p>Also, the <code>XMLStructure</code>s that are created by this factory
92  * may contain state specific to the <code>XMLSignature</code> and are not
93  * intended to be reusable.
94  *
95  * <h2>Creating XMLSignatures from scratch</h2>
96  *
97  * <p>Once the <code>XMLSignatureFactory</code> has been created, objects
98  * can be instantiated by calling the appropriate method. For example, a
99  * {@link Reference} instance may be created by invoking one of the
100  * {@link #newReference newReference} methods.
101  *
102  * <h2>Unmarshalling XMLSignatures from XML</h2>
103  *
104  * <p>Alternatively, an <code>XMLSignature</code> may be created from an
105  * existing XML representation by invoking the {@link #unmarshalXMLSignature
106  * unmarshalXMLSignature} method and passing it a mechanism-specific
107  * {@link XMLValidateContext} instance containing the XML content:
108  *
109  * <pre>
110  * DOMValidateContext context = new DOMValidateContext(key, signatureElement);
111  * XMLSignature signature = factory.unmarshalXMLSignature(context);
112  * </pre>
113  *
114  * Each <code>XMLSignatureFactory</code> must support the required
115  * <code>XMLValidateContext</code> types for that factory type, but may support
116  * others. A DOM <code>XMLSignatureFactory</code> must support {@link
117  * DOMValidateContext} objects.
118  *
119  * <h2>Signing and marshalling XMLSignatures to XML</h2>
120  *
121  * Each <code>XMLSignature</code> created by the factory can also be
122  * marshalled to an XML representation and signed, by invoking the
123  * {@link XMLSignature#sign sign} method of the
124  * {@link XMLSignature} object and passing it a mechanism-specific
125  * {@link XMLSignContext} object containing the signing key and
126  * marshalling parameters (see {@link DOMSignContext}).
127  * For example:
128  *
129  * <pre>
130  *    DOMSignContext context = new DOMSignContext(privateKey, document);
131  *    signature.sign(context);
132  * </pre>
133  *
134  * <b>Concurrent Access</b>
135  * <p>The static methods of this class are guaranteed to be thread-safe.
136  * Multiple threads may concurrently invoke the static methods defined in this
137  * class with no ill effects.
138  *
139  * <p>However, this is not true for the non-static methods defined by this
140  * class. Unless otherwise documented by a specific provider, threads that
141  * need to access a single <code>XMLSignatureFactory</code> instance
142  * concurrently should synchronize amongst themselves and provide the
143  * necessary locking. Multiple threads each manipulating a different
144  * <code>XMLSignatureFactory</code> instance need not synchronize.
145  *
146  * @author Sean Mullan
147  * @author JSR 105 Expert Group
148  * @since 1.6
149  */
150 public abstract class XMLSignatureFactory {
151 
152     private String mechanismType;
153     private Provider provider;
154 
155     /**
156      * Default constructor, for invocation by subclasses.
157      */
XMLSignatureFactory()158     protected XMLSignatureFactory() {}
159 
160     /**
161      * Returns an <code>XMLSignatureFactory</code> that supports the
162      * specified XML processing mechanism and representation type (ex: "DOM").
163      *
164      * <p>This method uses the standard JCA provider lookup mechanism to
165      * locate and instantiate an <code>XMLSignatureFactory</code>
166      * implementation of the desired mechanism type. It traverses the list of
167      * registered security <code>Provider</code>s, starting with the most
168      * preferred <code>Provider</code>.  A new <code>XMLSignatureFactory</code>
169      * object from the first <code>Provider</code> that supports the specified
170      * mechanism is returned.
171      *
172      * <p>Note that the list of registered providers may be retrieved via
173      * the {@link Security#getProviders() Security.getProviders()} method.
174      *
175      * @implNote
176      * The JDK Reference Implementation additionally uses the
177      * {@code jdk.security.provider.preferred}
178      * {@link Security#getProperty(String) Security} property to determine
179      * the preferred provider order for the specified algorithm. This
180      * may be different than the order of providers returned by
181      * {@link Security#getProviders() Security.getProviders()}.
182      *
183      * @param mechanismType the type of the XML processing mechanism and
184      *    representation. See the {@code XMLSignatureFactory} section in the
185      *    <a href=
186      *    "{@docRoot}/../specs/security/standard-names.html#xml-signature-xmlsignaturefactorykeyinfofactorytransformservice-mechanisms">
187      *    Java Security Standard Algorithm Names Specification</a> for a list of
188      *    standard mechanism types.
189      * @return a new <code>XMLSignatureFactory</code>
190      * @throws NullPointerException if <code>mechanismType</code> is
191      *    <code>null</code>
192      * @throws NoSuchMechanismException if no <code>Provider</code> supports an
193      *    <code>XMLSignatureFactory</code> implementation for the specified
194      *    mechanism
195      * @see Provider
196      */
getInstance(String mechanismType)197     public static XMLSignatureFactory getInstance(String mechanismType) {
198         if (mechanismType == null) {
199             throw new NullPointerException("mechanismType cannot be null");
200         }
201         Provider[] provs = Security.getProviders();
202         for (Provider p : provs) {
203             Service s = p.getService("XMLSignatureFactory", mechanismType);
204             if (s != null) {
205                 Object obj = null;
206                 try {
207                     obj = s.newInstance(null);
208                 } catch (NoSuchAlgorithmException nsae) {
209                     throw new NoSuchMechanismException(nsae);
210                 }
211                 if (obj instanceof XMLSignatureFactory) {
212                     XMLSignatureFactory factory = (XMLSignatureFactory) obj;
213                     factory.mechanismType = mechanismType;
214                     factory.provider = p;
215                     return factory;
216                 }
217             }
218         }
219         throw new NoSuchMechanismException
220             ("Mechanism " + mechanismType + " not available");
221     }
222 
223     /**
224      * Returns an <code>XMLSignatureFactory</code> that supports the
225      * requested XML processing mechanism and representation type (ex: "DOM"),
226      * as supplied by the specified provider. Note that the specified
227      * <code>Provider</code> object does not have to be registered in the
228      * provider list.
229      *
230      * @param mechanismType the type of the XML processing mechanism and
231      *    representation. See the {@code XMLSignatureFactory} section in the
232      *    <a href=
233      *    "{@docRoot}/../specs/security/standard-names.html#xml-signature-xmlsignaturefactorykeyinfofactorytransformservice-mechanisms">
234      *    Java Security Standard Algorithm Names Specification</a> for a list of
235      *    standard mechanism types.
236      * @param provider the <code>Provider</code> object
237      * @return a new <code>XMLSignatureFactory</code>
238      * @throws NullPointerException if <code>provider</code> or
239      *    <code>mechanismType</code> is <code>null</code>
240      * @throws NoSuchMechanismException if an <code>XMLSignatureFactory</code>
241      *   implementation for the specified mechanism is not available
242      *   from the specified <code>Provider</code> object
243      * @see Provider
244      */
getInstance(String mechanismType, Provider provider)245     public static XMLSignatureFactory getInstance(String mechanismType,
246         Provider provider) {
247         if (mechanismType == null) {
248             throw new NullPointerException("mechanismType cannot be null");
249         } else if (provider == null) {
250             throw new NullPointerException("provider cannot be null");
251         }
252 
253         Service s = provider.getService("XMLSignatureFactory", mechanismType);
254         if (s != null) {
255             Object obj = null;
256             try {
257                 obj = s.newInstance(null);
258             } catch (NoSuchAlgorithmException nsae) {
259                 throw new NoSuchMechanismException(nsae);
260             }
261 
262             if (obj instanceof XMLSignatureFactory) {
263                 XMLSignatureFactory factory = (XMLSignatureFactory) obj;
264                 factory.mechanismType = mechanismType;
265                 factory.provider = provider;
266                 return factory;
267             }
268         }
269         throw new NoSuchMechanismException
270             ("Mechanism " + mechanismType + " not available from " +
271              provider.getName());
272     }
273 
274     /**
275      * Returns an <code>XMLSignatureFactory</code> that supports the
276      * requested XML processing mechanism and representation type (ex: "DOM"),
277      * as supplied by the specified provider. The specified provider must be
278      * registered in the security provider list.
279      *
280      * <p>Note that the list of registered providers may be retrieved via
281      * the {@link Security#getProviders() Security.getProviders()} method.
282      *
283      * @param mechanismType the type of the XML processing mechanism and
284      *    representation. See the {@code XMLSignatureFactory} section in the
285      *    <a href=
286      *    "{@docRoot}/../specs/security/standard-names.html#xml-signature-xmlsignaturefactorykeyinfofactorytransformservice-mechanisms">
287      *    Java Security Standard Algorithm Names Specification</a> for a list of
288      *    standard mechanism types.
289      * @param provider the string name of the provider
290      * @return a new <code>XMLSignatureFactory</code>
291      * @throws NoSuchProviderException if the specified provider is not
292      *    registered in the security provider list
293      * @throws NullPointerException if <code>provider</code> or
294      *    <code>mechanismType</code> is <code>null</code>
295      * @throws NoSuchMechanismException if an <code>XMLSignatureFactory</code>
296      *    implementation for the specified mechanism is not
297      *    available from the specified provider
298      * @see Provider
299      */
getInstance(String mechanismType, String provider)300     public static XMLSignatureFactory getInstance(String mechanismType,
301         String provider) throws NoSuchProviderException {
302         if (mechanismType == null) {
303             throw new NullPointerException("mechanismType cannot be null");
304         } else if (provider == null) {
305             throw new NullPointerException("provider cannot be null");
306         } else if (provider.length() == 0) {
307             throw new NoSuchProviderException();
308         }
309 
310         Provider p = Security.getProvider(provider);
311         if (p == null) {
312             throw new NoSuchProviderException("No such provider: " +
313                                               provider);
314         }
315         Service s = p.getService("XMLSignatureFactory", mechanismType);
316         if (s != null) {
317             Object obj = null;
318             try {
319                 obj = s.newInstance(null);
320             } catch (NoSuchAlgorithmException nsae) {
321                 throw new NoSuchMechanismException(nsae);
322             }
323             if (obj instanceof XMLSignatureFactory) {
324                 XMLSignatureFactory factory = (XMLSignatureFactory) obj;
325                 factory.mechanismType = mechanismType;
326                 factory.provider = p;
327                 return factory;
328             }
329         }
330         throw new NoSuchMechanismException
331             ("Mechanism " + mechanismType + " not available from " + provider);
332     }
333 
334     /**
335      * Returns an <code>XMLSignatureFactory</code> that supports the
336      * default XML processing mechanism and representation type ("DOM").
337      *
338      * <p>This method uses the standard JCA provider lookup mechanism to
339      * locate and instantiate an <code>XMLSignatureFactory</code>
340      * implementation of the default mechanism type. It traverses the list of
341      * registered security <code>Provider</code>s, starting with the most
342      * preferred <code>Provider</code>.  A new <code>XMLSignatureFactory</code>
343      * object from the first <code>Provider</code> that supports the DOM
344      * mechanism is returned.
345      *
346      * <p>Note that the list of registered providers may be retrieved via
347      * the {@link Security#getProviders() Security.getProviders()} method.
348      *
349      * @return a new <code>XMLSignatureFactory</code>
350      * @throws NoSuchMechanismException if no <code>Provider</code> supports an
351      *    <code>XMLSignatureFactory</code> implementation for the DOM
352      *    mechanism
353      * @see Provider
354      */
getInstance()355     public static XMLSignatureFactory getInstance() {
356         return getInstance("DOM");
357     }
358 
359     /**
360      * Returns the type of the XML processing mechanism and representation
361      * supported by this <code>XMLSignatureFactory</code> (ex: "DOM").
362      *
363      * @return the XML processing mechanism type supported by this
364      *    <code>XMLSignatureFactory</code>
365      */
getMechanismType()366     public final String getMechanismType() {
367         return mechanismType;
368     }
369 
370     /**
371      * Returns the provider of this <code>XMLSignatureFactory</code>.
372      *
373      * @return the provider of this <code>XMLSignatureFactory</code>
374      */
getProvider()375     public final Provider getProvider() {
376         return provider;
377     }
378 
379     /**
380      * Creates an <code>XMLSignature</code> and initializes it with the contents
381      * of the specified <code>SignedInfo</code> and <code>KeyInfo</code>
382      * objects.
383      *
384      * @param si the signed info
385      * @param ki the key info (may be <code>null</code>)
386      * @return an <code>XMLSignature</code>
387      * @throws NullPointerException if <code>si</code> is <code>null</code>
388      */
newXMLSignature(SignedInfo si, KeyInfo ki)389     public abstract XMLSignature newXMLSignature(SignedInfo si, KeyInfo ki);
390 
391     /**
392      * Creates an <code>XMLSignature</code> and initializes it with the
393      * specified parameters.
394      *
395      * @param si the signed info
396      * @param ki the key info (may be <code>null</code>)
397      * @param objects a list of {@link XMLObject}s (may be empty or
398      *    <code>null</code>)
399      * @param id the Id (may be <code>null</code>)
400      * @param signatureValueId the SignatureValue Id (may be <code>null</code>)
401      * @return an <code>XMLSignature</code>
402      * @throws NullPointerException if <code>si</code> is <code>null</code>
403      * @throws ClassCastException if any of the <code>objects</code> are not of
404      *    type <code>XMLObject</code>
405      */
newXMLSignature(SignedInfo si, KeyInfo ki, List<? extends XMLObject> objects, String id, String signatureValueId)406     public abstract XMLSignature newXMLSignature(SignedInfo si, KeyInfo ki,
407         List<? extends XMLObject> objects, String id, String signatureValueId);
408 
409     /**
410      * Creates a <code>Reference</code> with the specified URI and digest
411      * method.
412      *
413      * @param uri the reference URI (may be <code>null</code>)
414      * @param dm the digest method
415      * @return a <code>Reference</code>
416      * @throws IllegalArgumentException if <code>uri</code> is not RFC 2396
417      *    compliant
418      * @throws NullPointerException if <code>dm</code> is <code>null</code>
419      */
newReference(String uri, DigestMethod dm)420     public abstract Reference newReference(String uri, DigestMethod dm);
421 
422     /**
423      * Creates a <code>Reference</code> with the specified parameters.
424      *
425      * @param uri the reference URI (may be <code>null</code>)
426      * @param dm the digest method
427      * @param transforms a list of {@link Transform}s. The list is defensively
428      *    copied to protect against subsequent modification. May be
429      *    <code>null</code> or empty.
430      * @param type the reference type, as a URI (may be <code>null</code>)
431      * @param id the reference ID (may be <code>null</code>)
432      * @return a <code>Reference</code>
433      * @throws ClassCastException if any of the <code>transforms</code> are
434      *    not of type <code>Transform</code>
435      * @throws IllegalArgumentException if <code>uri</code> is not RFC 2396
436      *    compliant
437      * @throws NullPointerException if <code>dm</code> is <code>null</code>
438      */
newReference(String uri, DigestMethod dm, List<? extends Transform> transforms, String type, String id)439     public abstract Reference newReference(String uri, DigestMethod dm,
440         List<? extends Transform> transforms, String type, String id);
441 
442     /**
443      * Creates a <code>Reference</code> with the specified parameters and
444      * pre-calculated digest value.
445      *
446      * <p>This method is useful when the digest value of a
447      * <code>Reference</code> has been previously computed. See for example,
448      * the
449      * <a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=dss">
450      * OASIS-DSS (Digital Signature Services)</a> specification.
451      *
452      * @param uri the reference URI (may be <code>null</code>)
453      * @param dm the digest method
454      * @param transforms a list of {@link Transform}s. The list is defensively
455      *    copied to protect against subsequent modification. May be
456      *    <code>null</code> or empty.
457      * @param type the reference type, as a URI (may be <code>null</code>)
458      * @param id the reference ID (may be <code>null</code>)
459      * @param digestValue the digest value. The array is cloned to protect
460      *    against subsequent modification.
461      * @return a <code>Reference</code>
462      * @throws ClassCastException if any of the <code>transforms</code> are
463      *    not of type <code>Transform</code>
464      * @throws IllegalArgumentException if <code>uri</code> is not RFC 2396
465      *    compliant
466      * @throws NullPointerException if <code>dm</code> or
467      *    <code>digestValue</code> is <code>null</code>
468      */
newReference(String uri, DigestMethod dm, List<? extends Transform> transforms, String type, String id, byte[] digestValue)469     public abstract Reference newReference(String uri, DigestMethod dm,
470         List<? extends Transform> transforms, String type, String id,
471         byte[] digestValue);
472 
473     /**
474      * Creates a <code>Reference</code> with the specified parameters.
475      *
476      * <p>This method is useful when a list of transforms have already been
477      * applied to the <code>Reference</code>. See for example,
478      * the
479      * <a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=dss">
480      * OASIS-DSS (Digital Signature Services)</a> specification.
481      *
482      * <p>When an <code>XMLSignature</code> containing this reference is
483      * generated, the specified <code>transforms</code> (if non-null) are
484      * applied to the specified <code>result</code>. The
485      * <code>Transforms</code> element of the resulting <code>Reference</code>
486      * element is set to the concatenation of the
487      * <code>appliedTransforms</code> and <code>transforms</code>.
488      *
489      * @param uri the reference URI (may be <code>null</code>)
490      * @param dm the digest method
491      * @param appliedTransforms a list of {@link Transform}s that have
492      *    already been applied. The list is defensively
493      *    copied to protect against subsequent modification. The list must
494      *    contain at least one entry.
495      * @param result the result of processing the sequence of
496      *    <code>appliedTransforms</code>
497      * @param transforms a list of {@link Transform}s that are to be applied
498      *    when generating the signature. The list is defensively copied to
499      *    protect against subsequent modification. May be <code>null</code>
500      *    or empty.
501      * @param type the reference type, as a URI (may be <code>null</code>)
502      * @param id the reference ID (may be <code>null</code>)
503      * @return a <code>Reference</code>
504      * @throws ClassCastException if any of the transforms (in either list)
505      *    are not of type <code>Transform</code>
506      * @throws IllegalArgumentException if <code>uri</code> is not RFC 2396
507      *    compliant or <code>appliedTransforms</code> is empty
508      * @throws NullPointerException if <code>dm</code>,
509      *    <code>appliedTransforms</code> or <code>result</code> is
510      *    <code>null</code>
511      */
newReference(String uri, DigestMethod dm, List<? extends Transform> appliedTransforms, Data result, List<? extends Transform> transforms, String type, String id)512     public abstract Reference newReference(String uri, DigestMethod dm,
513         List<? extends Transform> appliedTransforms, Data result,
514         List<? extends Transform> transforms, String type, String id);
515 
516     /**
517      * Creates a <code>SignedInfo</code> with the specified canonicalization
518      * and signature methods, and list of one or more references.
519      *
520      * @param cm the canonicalization method
521      * @param sm the signature method
522      * @param references a list of one or more {@link Reference}s. The list is
523      *    defensively copied to protect against subsequent modification.
524      * @return a <code>SignedInfo</code>
525      * @throws ClassCastException if any of the references are not of
526      *    type <code>Reference</code>
527      * @throws IllegalArgumentException if <code>references</code> is empty
528      * @throws NullPointerException if any of the parameters
529      *    are <code>null</code>
530      */
newSignedInfo(CanonicalizationMethod cm, SignatureMethod sm, List<? extends Reference> references)531     public abstract SignedInfo newSignedInfo(CanonicalizationMethod cm,
532         SignatureMethod sm, List<? extends Reference> references);
533 
534     /**
535      * Creates a <code>SignedInfo</code> with the specified parameters.
536      *
537      * @param cm the canonicalization method
538      * @param sm the signature method
539      * @param references a list of one or more {@link Reference}s. The list is
540      *    defensively copied to protect against subsequent modification.
541      * @param id the id (may be <code>null</code>)
542      * @return a <code>SignedInfo</code>
543      * @throws ClassCastException if any of the references are not of
544      *    type <code>Reference</code>
545      * @throws IllegalArgumentException if <code>references</code> is empty
546      * @throws NullPointerException if <code>cm</code>, <code>sm</code>, or
547      *    <code>references</code> are <code>null</code>
548      */
newSignedInfo(CanonicalizationMethod cm, SignatureMethod sm, List<? extends Reference> references, String id)549     public abstract SignedInfo newSignedInfo(CanonicalizationMethod cm,
550         SignatureMethod sm, List<? extends Reference> references, String id);
551 
552     // Object factory methods
553     /**
554      * Creates an <code>XMLObject</code> from the specified parameters.
555      *
556      * @param content a list of {@link XMLStructure}s. The list
557      *    is defensively copied to protect against subsequent modification.
558      *    May be <code>null</code> or empty.
559      * @param id the Id (may be <code>null</code>)
560      * @param mimeType the mime type (may be <code>null</code>)
561      * @param encoding the encoding (may be <code>null</code>)
562      * @return an <code>XMLObject</code>
563      * @throws ClassCastException if <code>content</code> contains any
564      *    entries that are not of type {@link XMLStructure}
565      */
newXMLObject(List<? extends XMLStructure> content, String id, String mimeType, String encoding)566     public abstract XMLObject newXMLObject(List<? extends XMLStructure> content,
567         String id, String mimeType, String encoding);
568 
569     /**
570      * Creates a <code>Manifest</code> containing the specified
571      * list of {@link Reference}s.
572      *
573      * @param references a list of one or more <code>Reference</code>s. The list
574      *    is defensively copied to protect against subsequent modification.
575      * @return a <code>Manifest</code>
576      * @throws NullPointerException if <code>references</code> is
577      *    <code>null</code>
578      * @throws IllegalArgumentException if <code>references</code> is empty
579      * @throws ClassCastException if <code>references</code> contains any
580      *    entries that are not of type {@link Reference}
581      */
newManifest(List<? extends Reference> references)582     public abstract Manifest newManifest(List<? extends Reference> references);
583 
584     /**
585      * Creates a <code>Manifest</code> containing the specified
586      * list of {@link Reference}s and optional id.
587      *
588      * @param references a list of one or more <code>Reference</code>s. The list
589      *    is defensively copied to protect against subsequent modification.
590      * @param id the id (may be <code>null</code>)
591      * @return a <code>Manifest</code>
592      * @throws NullPointerException if <code>references</code> is
593      *    <code>null</code>
594      * @throws IllegalArgumentException if <code>references</code> is empty
595      * @throws ClassCastException if <code>references</code> contains any
596      *    entries that are not of type {@link Reference}
597      */
newManifest(List<? extends Reference> references, String id)598     public abstract Manifest newManifest(List<? extends Reference> references,
599         String id);
600 
601     /**
602      * Creates a <code>SignatureProperty</code> containing the specified
603      * list of {@link XMLStructure}s, target URI and optional id.
604      *
605      * @param content a list of one or more <code>XMLStructure</code>s. The list
606      *    is defensively copied to protect against subsequent modification.
607      * @param target the target URI of the Signature that this property applies
608      *    to
609      * @param id the id (may be <code>null</code>)
610      * @return a <code>SignatureProperty</code>
611      * @throws NullPointerException if <code>content</code> or
612      *    <code>target</code> is <code>null</code>
613      * @throws IllegalArgumentException if <code>content</code> is empty
614      * @throws ClassCastException if <code>content</code> contains any
615      *    entries that are not of type {@link XMLStructure}
616      */
newSignatureProperty(List<? extends XMLStructure> content, String target, String id)617     public abstract SignatureProperty newSignatureProperty
618         (List<? extends XMLStructure> content, String target, String id);
619 
620     /**
621      * Creates a <code>SignatureProperties</code> containing the specified
622      * list of {@link SignatureProperty}s and optional id.
623      *
624      * @param properties a list of one or more <code>SignatureProperty</code>s.
625      *    The list is defensively copied to protect against subsequent
626      *    modification.
627      * @param id the id (may be <code>null</code>)
628      * @return a <code>SignatureProperties</code>
629      * @throws NullPointerException if <code>properties</code>
630      *    is <code>null</code>
631      * @throws IllegalArgumentException if <code>properties</code> is empty
632      * @throws ClassCastException if <code>properties</code> contains any
633      *    entries that are not of type {@link SignatureProperty}
634      */
newSignatureProperties(List<? extends SignatureProperty> properties, String id)635     public abstract SignatureProperties newSignatureProperties
636         (List<? extends SignatureProperty> properties, String id);
637 
638     // Algorithm factory methods
639     /**
640      * Creates a <code>DigestMethod</code> for the specified algorithm URI
641      * and parameters.
642      *
643      * @param algorithm the URI identifying the digest algorithm
644      * @param params algorithm-specific digest parameters (may be
645      *    <code>null</code>)
646      * @return the <code>DigestMethod</code>
647      * @throws InvalidAlgorithmParameterException if the specified parameters
648      *    are inappropriate for the requested algorithm
649      * @throws NoSuchAlgorithmException if an implementation of the
650      *    specified algorithm cannot be found
651      * @throws NullPointerException if <code>algorithm</code> is
652      *    <code>null</code>
653      */
newDigestMethod(String algorithm, DigestMethodParameterSpec params)654     public abstract DigestMethod newDigestMethod(String algorithm,
655         DigestMethodParameterSpec params) throws NoSuchAlgorithmException,
656         InvalidAlgorithmParameterException;
657 
658     /**
659      * Creates a <code>SignatureMethod</code> for the specified algorithm URI
660      * and parameters.
661      *
662      * @param algorithm the URI identifying the signature algorithm
663      * @param params algorithm-specific signature parameters (may be
664      *    <code>null</code>)
665      * @return the <code>SignatureMethod</code>
666      * @throws InvalidAlgorithmParameterException if the specified parameters
667      *    are inappropriate for the requested algorithm
668      * @throws NoSuchAlgorithmException if an implementation of the
669      *    specified algorithm cannot be found
670      * @throws NullPointerException if <code>algorithm</code> is
671      *    <code>null</code>
672      */
newSignatureMethod(String algorithm, SignatureMethodParameterSpec params)673     public abstract SignatureMethod newSignatureMethod(String algorithm,
674         SignatureMethodParameterSpec params) throws NoSuchAlgorithmException,
675         InvalidAlgorithmParameterException;
676 
677     /**
678      * Creates a <code>Transform</code> for the specified algorithm URI
679      * and parameters.
680      *
681      * @param algorithm the URI identifying the transform algorithm
682      * @param params algorithm-specific transform parameters (may be
683      *    <code>null</code>)
684      * @return the <code>Transform</code>
685      * @throws InvalidAlgorithmParameterException if the specified parameters
686      *    are inappropriate for the requested algorithm
687      * @throws NoSuchAlgorithmException if an implementation of the
688      *    specified algorithm cannot be found
689      * @throws NullPointerException if <code>algorithm</code> is
690      *    <code>null</code>
691      */
newTransform(String algorithm, TransformParameterSpec params)692     public abstract Transform newTransform(String algorithm,
693         TransformParameterSpec params) throws NoSuchAlgorithmException,
694         InvalidAlgorithmParameterException;
695 
696     /**
697      * Creates a <code>Transform</code> for the specified algorithm URI
698      * and parameters. The parameters are specified as a mechanism-specific
699      * <code>XMLStructure</code> (ex: {@link DOMStructure}). This method is
700      * useful when the parameters are in XML form or there is no standard
701      * class for specifying the parameters.
702      *
703      * @param algorithm the URI identifying the transform algorithm
704      * @param params a mechanism-specific XML structure from which to
705      *   unmarshal the parameters from (may be <code>null</code> if
706      *   not required or optional)
707      * @return the <code>Transform</code>
708      * @throws ClassCastException if the type of <code>params</code> is
709      *   inappropriate for this <code>XMLSignatureFactory</code>
710      * @throws InvalidAlgorithmParameterException if the specified parameters
711      *    are inappropriate for the requested algorithm
712      * @throws NoSuchAlgorithmException if an implementation of the
713      *    specified algorithm cannot be found
714      * @throws NullPointerException if <code>algorithm</code> is
715      *    <code>null</code>
716      */
newTransform(String algorithm, XMLStructure params)717     public abstract Transform newTransform(String algorithm,
718         XMLStructure params) throws NoSuchAlgorithmException,
719         InvalidAlgorithmParameterException;
720 
721     /**
722      * Creates a <code>CanonicalizationMethod</code> for the specified
723      * algorithm URI and parameters.
724      *
725      * @param algorithm the URI identifying the canonicalization algorithm
726      * @param params algorithm-specific canonicalization parameters (may be
727      *    <code>null</code>)
728      * @return the <code>CanonicalizationMethod</code>
729      * @throws InvalidAlgorithmParameterException if the specified parameters
730      *    are inappropriate for the requested algorithm
731      * @throws NoSuchAlgorithmException if an implementation of the
732      *    specified algorithm cannot be found
733      * @throws NullPointerException if <code>algorithm</code> is
734      *    <code>null</code>
735      */
newCanonicalizationMethod( String algorithm, C14NMethodParameterSpec params)736     public abstract CanonicalizationMethod newCanonicalizationMethod(
737         String algorithm, C14NMethodParameterSpec params)
738         throws NoSuchAlgorithmException, InvalidAlgorithmParameterException;
739 
740     /**
741      * Creates a <code>CanonicalizationMethod</code> for the specified
742      * algorithm URI and parameters. The parameters are specified as a
743      * mechanism-specific <code>XMLStructure</code> (ex: {@link DOMStructure}).
744      * This method is useful when the parameters are in XML form or there is
745      * no standard class for specifying the parameters.
746      *
747      * @param algorithm the URI identifying the canonicalization algorithm
748      * @param params a mechanism-specific XML structure from which to
749      *   unmarshal the parameters from (may be <code>null</code> if
750      *   not required or optional)
751      * @return the <code>CanonicalizationMethod</code>
752      * @throws ClassCastException if the type of <code>params</code> is
753      *   inappropriate for this <code>XMLSignatureFactory</code>
754      * @throws InvalidAlgorithmParameterException if the specified parameters
755      *    are inappropriate for the requested algorithm
756      * @throws NoSuchAlgorithmException if an implementation of the
757      *    specified algorithm cannot be found
758      * @throws NullPointerException if <code>algorithm</code> is
759      *    <code>null</code>
760      */
newCanonicalizationMethod( String algorithm, XMLStructure params)761     public abstract CanonicalizationMethod newCanonicalizationMethod(
762         String algorithm, XMLStructure params)
763         throws NoSuchAlgorithmException, InvalidAlgorithmParameterException;
764 
765     /**
766      * Returns a <code>KeyInfoFactory</code> that creates <code>KeyInfo</code>
767      * objects. The returned <code>KeyInfoFactory</code> has the same
768      * mechanism type and provider as this <code>XMLSignatureFactory</code>.
769      *
770      * @return a <code>KeyInfoFactory</code>
771      * @throws NoSuchMechanismException if a <code>KeyFactory</code>
772      *    implementation with the same mechanism type and provider
773      *    is not available
774      */
getKeyInfoFactory()775     public final KeyInfoFactory getKeyInfoFactory() {
776         return KeyInfoFactory.getInstance(getMechanismType(), getProvider());
777     }
778 
779     /**
780      * Unmarshals a new <code>XMLSignature</code> instance from a
781      * mechanism-specific <code>XMLValidateContext</code> instance.
782      *
783      * @param context a mechanism-specific context from which to unmarshal the
784      *    signature from
785      * @return the <code>XMLSignature</code>
786      * @throws NullPointerException if <code>context</code> is
787      *    <code>null</code>
788      * @throws ClassCastException if the type of <code>context</code> is
789      *    inappropriate for this factory
790      * @throws MarshalException if an unrecoverable exception occurs
791      *    during unmarshalling
792      */
unmarshalXMLSignature(XMLValidateContext context)793     public abstract XMLSignature unmarshalXMLSignature
794         (XMLValidateContext context) throws MarshalException;
795 
796     /**
797      * Unmarshals a new <code>XMLSignature</code> instance from a
798      * mechanism-specific <code>XMLStructure</code> instance.
799      * This method is useful if you only want to unmarshal (and not
800      * validate) an <code>XMLSignature</code>.
801      *
802      * @param xmlStructure a mechanism-specific XML structure from which to
803      *    unmarshal the signature from
804      * @return the <code>XMLSignature</code>
805      * @throws NullPointerException if <code>xmlStructure</code> is
806      *    <code>null</code>
807      * @throws ClassCastException if the type of <code>xmlStructure</code> is
808      *    inappropriate for this factory
809      * @throws MarshalException if an unrecoverable exception occurs
810      *    during unmarshalling
811      */
unmarshalXMLSignature(XMLStructure xmlStructure)812     public abstract XMLSignature unmarshalXMLSignature
813         (XMLStructure xmlStructure) throws MarshalException;
814 
815     /**
816      * Indicates whether a specified feature is supported.
817      *
818      * @param feature the feature name (as an absolute URI)
819      * @return <code>true</code> if the specified feature is supported,
820      *    <code>false</code> otherwise
821      * @throws NullPointerException if <code>feature</code> is <code>null</code>
822      */
isFeatureSupported(String feature)823     public abstract boolean isFeatureSupported(String feature);
824 
825     /**
826      * Returns a reference to the <code>URIDereferencer</code> that is used by
827      * default to dereference URIs in {@link Reference} objects.
828      *
829      * @return a reference to the default <code>URIDereferencer</code> (never
830      *    <code>null</code>)
831      */
getURIDereferencer()832     public abstract URIDereferencer getURIDereferencer();
833 }
834