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