793 lines · 35.3 KB · Java
RawDownload
/* * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *//* * $Id: XMLSignatureFactory.java,v 1.14 2005/09/15 14:29:01 mullan Exp $ */package javax.xml.crypto.dsig; import javax.xml.crypto.Data;import javax.xml.crypto.MarshalException;import javax.xml.crypto.NoSuchMechanismException;import javax.xml.crypto.URIDereferencer;import javax.xml.crypto.XMLStructure;import javax.xml.crypto.dom.DOMStructure;import javax.xml.crypto.dsig.keyinfo.KeyInfo;import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;import javax.xml.crypto.dsig.spec.*;import javax.xml.crypto.dsig.dom.DOMValidateContext;import javax.xml.crypto.dsig.dom.DOMSignContext; import java.security.InvalidAlgorithmParameterException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.Provider;import java.security.Security;import java.util.List; import sun.security.jca.*;import sun.security.jca.GetInstance.Instance; /** * A factory for creating {@link XMLSignature} objects from scratch or * for unmarshalling an <code>XMLSignature</code> object from a corresponding * XML representation. * * <h2>XMLSignatureFactory Type</h2> * * <p>Each instance of <code>XMLSignatureFactory</code> supports a specific * XML mechanism type. To create an <code>XMLSignatureFactory</code>, call one * of the static {@link #getInstance getInstance} methods, passing in the XML * mechanism type desired, for example: * * <blockquote><code> * XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM"); * </code></blockquote> * * <p>The objects that this factory produces will be based * on DOM and abide by the DOM interoperability requirements as defined in the * <a href="../../../../../technotes/guides/security/xmldsig/overview.html#DOM Mechanism Requirements"> * DOM Mechanism Requirements</a> section of the API overview. See the * <a href="../../../../../technotes/guides/security/xmldsig/overview.html#Service Provider"> * Service Providers</a> section of the API overview for a list of standard * mechanism types. * * <p><code>XMLSignatureFactory</code> implementations are registered and loaded * using the {@link java.security.Provider} mechanism. * For example, a service provider that supports the * DOM mechanism would be specified in the <code>Provider</code> subclass as: * <pre> *     put("XMLSignatureFactory.DOM", "org.example.DOMXMLSignatureFactory"); * </pre> * * <p>An implementation MUST minimally support the default mechanism type: DOM. * * <p>Note that a caller must use the same <code>XMLSignatureFactory</code> * instance to create the <code>XMLStructure</code>s of a particular * <code>XMLSignature</code> that is to be generated. The behavior is * undefined if <code>XMLStructure</code>s from different providers or * different mechanism types are used together. * * <p>Also, the <code>XMLStructure</code>s that are created by this factory * may contain state specific to the <code>XMLSignature</code> and are not * intended to be reusable. * * <h2>Creating XMLSignatures from scratch</h2> * * <p>Once the <code>XMLSignatureFactory</code> has been created, objects * can be instantiated by calling the appropriate method. For example, a * {@link Reference} instance may be created by invoking one of the * {@link #newReference newReference} methods. * * <h2>Unmarshalling XMLSignatures from XML</h2> * * <p>Alternatively, an <code>XMLSignature</code> may be created from an * existing XML representation by invoking the {@link #unmarshalXMLSignature * unmarshalXMLSignature} method and passing it a mechanism-specific * {@link XMLValidateContext} instance containing the XML content: * * <pre> * DOMValidateContext context = new DOMValidateContext(key, signatureElement); * XMLSignature signature = factory.unmarshalXMLSignature(context); * </pre> * * Each <code>XMLSignatureFactory</code> must support the required * <code>XMLValidateContext</code> types for that factory type, but may support * others. A DOM <code>XMLSignatureFactory</code> must support {@link * DOMValidateContext} objects. * * <h2>Signing and marshalling XMLSignatures to XML</h2> * * Each <code>XMLSignature</code> created by the factory can also be * marshalled to an XML representation and signed, by invoking the * {@link XMLSignature#sign sign} method of the * {@link XMLSignature} object and passing it a mechanism-specific * {@link XMLSignContext} object containing the signing key and * marshalling parameters (see {@link DOMSignContext}). * For example: * * <pre> *    DOMSignContext context = new DOMSignContext(privateKey, document); *    signature.sign(context); * </pre> * * <b>Concurrent Access</b> * <p>The static methods of this class are guaranteed to be thread-safe. * Multiple threads may concurrently invoke the static methods defined in this * class with no ill effects. * * <p>However, this is not true for the non-static methods defined by this * class. Unless otherwise documented by a specific provider, threads that * need to access a single <code>XMLSignatureFactory</code> instance * concurrently should synchronize amongst themselves and provide the * necessary locking. Multiple threads each manipulating a different * <code>XMLSignatureFactory</code> instance need not synchronize. * * @author Sean Mullan * @author JSR 105 Expert Group * @since 1.6 */public abstract class XMLSignatureFactory {     private String mechanismType;    private Provider provider;     /**     * Default constructor, for invocation by subclasses.     */    protected XMLSignatureFactory() {}     /**     * Returns an <code>XMLSignatureFactory</code> that supports the     * specified XML processing mechanism and representation type (ex: "DOM").     *     * <p>This method uses the standard JCA provider lookup mechanism to     * locate and instantiate an <code>XMLSignatureFactory</code>     * implementation of the desired mechanism type. It traverses the list of     * registered security <code>Provider</code>s, starting with the most     * preferred <code>Provider</code>.  A new <code>XMLSignatureFactory</code>     * object from the first <code>Provider</code> that supports the specified     * mechanism is returned.     *     * <p>Note that the list of registered providers may be retrieved via     * the {@link Security#getProviders() Security.getProviders()} method.     *     * @param mechanismType the type of the XML processing mechanism and     *    representation. See the <a     *    href="../../../../../technotes/guides/security/xmldsig/overview.html#Service Provider">     *    Service Providers</a> section of the API overview for a list of     *    standard mechanism types.     * @return a new <code>XMLSignatureFactory</code>     * @throws NullPointerException if <code>mechanismType</code> is     *    <code>null</code>     * @throws NoSuchMechanismException if no <code>Provider</code> supports an     *    <code>XMLSignatureFactory</code> implementation for the specified     *    mechanism     * @see Provider     */    public static XMLSignatureFactory getInstance(String mechanismType) {        if (mechanismType == null) {            throw new NullPointerException("mechanismType cannot be null");        }        Instance instance;        try {            instance = GetInstance.getInstance                ("XMLSignatureFactory", null, mechanismType);        } catch (NoSuchAlgorithmException nsae) {            throw new NoSuchMechanismException(nsae);        }        XMLSignatureFactory factory = (XMLSignatureFactory) instance.impl;        factory.mechanismType = mechanismType;        factory.provider = instance.provider;        return factory;    }     /**     * Returns an <code>XMLSignatureFactory</code> that supports the     * requested XML processing mechanism and representation type (ex: "DOM"),     * as supplied by the specified provider. Note that the specified     * <code>Provider</code> object does not have to be registered in the     * provider list.     *     * @param mechanismType the type of the XML processing mechanism and     *    representation. See the <a     *    href="../../../../../technotes/guides/security/xmldsig/overview.html#Service Provider">     *    Service Providers</a> section of the API overview for a list of     *    standard mechanism types.     * @param provider the <code>Provider</code> object     * @return a new <code>XMLSignatureFactory</code>     * @throws NullPointerException if <code>provider</code> or     *    <code>mechanismType</code> is <code>null</code>     * @throws NoSuchMechanismException if an <code>XMLSignatureFactory</code>     *   implementation for the specified mechanism is not available     *   from the specified <code>Provider</code> object     * @see Provider     */    public static XMLSignatureFactory getInstance(String mechanismType,        Provider provider) {        if (mechanismType == null) {            throw new NullPointerException("mechanismType cannot be null");        } else if (provider == null) {            throw new NullPointerException("provider cannot be null");        }         Instance instance;        try {            instance = GetInstance.getInstance                ("XMLSignatureFactory", null, mechanismType, provider);        } catch (NoSuchAlgorithmException nsae) {            throw new NoSuchMechanismException(nsae);        }        XMLSignatureFactory factory = (XMLSignatureFactory) instance.impl;        factory.mechanismType = mechanismType;        factory.provider = instance.provider;        return factory;    }     /**     * Returns an <code>XMLSignatureFactory</code> that supports the     * requested XML processing mechanism and representation type (ex: "DOM"),     * as supplied by the specified provider. The specified provider must be     * registered in the security provider list.     *     * <p>Note that the list of registered providers may be retrieved via     * the {@link Security#getProviders() Security.getProviders()} method.     *     * @param mechanismType the type of the XML processing mechanism and     *    representation. See the <a     *    href="../../../../../technotes/guides/security/xmldsig/overview.html#Service Provider">     *    Service Providers</a> section of the API overview for a list of     *    standard mechanism types.     * @param provider the string name of the provider     * @return a new <code>XMLSignatureFactory</code>     * @throws NoSuchProviderException if the specified provider is not     *    registered in the security provider list     * @throws NullPointerException if <code>provider</code> or     *    <code>mechanismType</code> is <code>null</code>     * @throws NoSuchMechanismException if an <code>XMLSignatureFactory</code>     *    implementation for the specified mechanism is not     *    available from the specified provider     * @see Provider     */    public static XMLSignatureFactory getInstance(String mechanismType,        String provider) throws NoSuchProviderException {        if (mechanismType == null) {            throw new NullPointerException("mechanismType cannot be null");        } else if (provider == null) {            throw new NullPointerException("provider cannot be null");        } else if (provider.length() == 0) {            throw new NoSuchProviderException();        }         Instance instance;        try {            instance = GetInstance.getInstance                ("XMLSignatureFactory", null, mechanismType, provider);        } catch (NoSuchAlgorithmException nsae) {            throw new NoSuchMechanismException(nsae);        }        XMLSignatureFactory factory = (XMLSignatureFactory) instance.impl;        factory.mechanismType = mechanismType;        factory.provider = instance.provider;        return factory;    }     /**     * Returns an <code>XMLSignatureFactory</code> that supports the     * default XML processing mechanism and representation type ("DOM").     *     * <p>This method uses the standard JCA provider lookup mechanism to     * locate and instantiate an <code>XMLSignatureFactory</code>     * implementation of the default mechanism type. It traverses the list of     * registered security <code>Provider</code>s, starting with the most     * preferred <code>Provider</code>.  A new <code>XMLSignatureFactory</code>     * object from the first <code>Provider</code> that supports the DOM     * mechanism is returned.     *     * <p>Note that the list of registered providers may be retrieved via     * the {@link Security#getProviders() Security.getProviders()} method.     *     * @return a new <code>XMLSignatureFactory</code>     * @throws NoSuchMechanismException if no <code>Provider</code> supports an     *    <code>XMLSignatureFactory</code> implementation for the DOM     *    mechanism     * @see Provider     */    public static XMLSignatureFactory getInstance() {        return getInstance("DOM");    }     /**     * Returns the type of the XML processing mechanism and representation     * supported by this <code>XMLSignatureFactory</code> (ex: "DOM").     *     * @return the XML processing mechanism type supported by this     *    <code>XMLSignatureFactory</code>     */    public final String getMechanismType() {        return mechanismType;    }     /**     * Returns the provider of this <code>XMLSignatureFactory</code>.     *     * @return the provider of this <code>XMLSignatureFactory</code>     */    public final Provider getProvider() {        return provider;    }     /**     * Creates an <code>XMLSignature</code> and initializes it with the contents     * of the specified <code>SignedInfo</code> and <code>KeyInfo</code>     * objects.     *     * @param si the signed info     * @param ki the key info (may be <code>null</code>)     * @return an <code>XMLSignature</code>     * @throws NullPointerException if <code>si</code> is <code>null</code>     */    public abstract XMLSignature newXMLSignature(SignedInfo si, KeyInfo ki);     /**     * Creates an <code>XMLSignature</code> and initializes it with the     * specified parameters.     *     * @param si the signed info     * @param ki the key info (may be <code>null</code>)     * @param objects a list of {@link XMLObject}s (may be empty or     *    <code>null</code>)     * @param id the Id (may be <code>null</code>)     * @param signatureValueId the SignatureValue Id (may be <code>null</code>)     * @return an <code>XMLSignature</code>     * @throws NullPointerException if <code>si</code> is <code>null</code>     * @throws ClassCastException if any of the <code>objects</code> are not of     *    type <code>XMLObject</code>     */    public abstract XMLSignature newXMLSignature(SignedInfo si, KeyInfo ki,        List objects, String id, String signatureValueId);     /**     * Creates a <code>Reference</code> with the specified URI and digest     * method.     *     * @param uri the reference URI (may be <code>null</code>)     * @param dm the digest method     * @return a <code>Reference</code>     * @throws IllegalArgumentException if <code>uri</code> is not RFC 2396     *    compliant     * @throws NullPointerException if <code>dm</code> is <code>null</code>     */    public abstract Reference newReference(String uri, DigestMethod dm);     /**     * Creates a <code>Reference</code> with the specified parameters.     *     * @param uri the reference URI (may be <code>null</code>)     * @param dm the digest method     * @param transforms a list of {@link Transform}s. The list is defensively     *    copied to protect against subsequent modification. May be     *    <code>null</code> or empty.     * @param type the reference type, as a URI (may be <code>null</code>)     * @param id the reference ID (may be <code>null</code>)     * @return a <code>Reference</code>     * @throws ClassCastException if any of the <code>transforms</code> are     *    not of type <code>Transform</code>     * @throws IllegalArgumentException if <code>uri</code> is not RFC 2396     *    compliant     * @throws NullPointerException if <code>dm</code> is <code>null</code>     */    public abstract Reference newReference(String uri, DigestMethod dm,        List transforms, String type, String id);     /**     * Creates a <code>Reference</code> with the specified parameters and     * pre-calculated digest value.     *     * <p>This method is useful when the digest value of a     * <code>Reference</code> has been previously computed. See for example,     * the     * <a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=dss">     * OASIS-DSS (Digital Signature Services)</a> specification.     *     * @param uri the reference URI (may be <code>null</code>)     * @param dm the digest method     * @param transforms a list of {@link Transform}s. The list is defensively     *    copied to protect against subsequent modification. May be     *    <code>null</code> or empty.     * @param type the reference type, as a URI (may be <code>null</code>)     * @param id the reference ID (may be <code>null</code>)     * @param digestValue the digest value. The array is cloned to protect     *    against subsequent modification.     * @return a <code>Reference</code>     * @throws ClassCastException if any of the <code>transforms</code> are     *    not of type <code>Transform</code>     * @throws IllegalArgumentException if <code>uri</code> is not RFC 2396     *    compliant     * @throws NullPointerException if <code>dm</code> or     *    <code>digestValue</code> is <code>null</code>     */    public abstract Reference newReference(String uri, DigestMethod dm,        List transforms, String type, String id, byte[] digestValue);     /**     * Creates a <code>Reference</code> with the specified parameters.     *     * <p>This method is useful when a list of transforms have already been     * applied to the <code>Reference</code>. See for example,     * the     * <a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=dss">     * OASIS-DSS (Digital Signature Services)</a> specification.     *     * <p>When an <code>XMLSignature</code> containing this reference is     * generated, the specified <code>transforms</code> (if non-null) are     * applied to the specified <code>result</code>. The     * <code>Transforms</code> element of the resulting <code>Reference</code>     * element is set to the concatenation of the     * <code>appliedTransforms</code> and <code>transforms</code>.     *     * @param uri the reference URI (may be <code>null</code>)     * @param dm the digest method     * @param appliedTransforms a list of {@link Transform}s that have     *    already been applied. The list is defensively     *    copied to protect against subsequent modification. The list must     *    contain at least one entry.     * @param result the result of processing the sequence of     *    <code>appliedTransforms</code>     * @param transforms a list of {@link Transform}s that are to be applied     *    when generating the signature. The list is defensively copied to     *    protect against subsequent modification. May be <code>null</code>     *    or empty.     * @param type the reference type, as a URI (may be <code>null</code>)     * @param id the reference ID (may be <code>null</code>)     * @return a <code>Reference</code>     * @throws ClassCastException if any of the transforms (in either list)     *    are not of type <code>Transform</code>     * @throws IllegalArgumentException if <code>uri</code> is not RFC 2396     *    compliant or <code>appliedTransforms</code> is empty     * @throws NullPointerException if <code>dm</code>,     *    <code>appliedTransforms</code> or <code>result</code> is     *    <code>null</code>     */    public abstract Reference newReference(String uri, DigestMethod dm,        List appliedTransforms, Data result, List transforms, String type,        String id);     /**     * Creates a <code>SignedInfo</code> with the specified canonicalization     * and signature methods, and list of one or more references.     *     * @param cm the canonicalization method     * @param sm the signature method     * @param references a list of one or more {@link Reference}s. The list is     *    defensively copied to protect against subsequent modification.     * @return a <code>SignedInfo</code>     * @throws ClassCastException if any of the references are not of     *    type <code>Reference</code>     * @throws IllegalArgumentException if <code>references</code> is empty     * @throws NullPointerException if any of the parameters     *    are <code>null</code>     */    public abstract SignedInfo newSignedInfo(CanonicalizationMethod cm,        SignatureMethod sm, List references);     /**     * Creates a <code>SignedInfo</code> with the specified parameters.     *     * @param cm the canonicalization method     * @param sm the signature method     * @param references a list of one or more {@link Reference}s. The list is

Lines 1–500 of 793.