Home » openjdk-7 » javax » xml » crypto » dsig » keyinfo » [javadoc | source]

    1   /*
    2    * Copyright (c) 2005, 2006, 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: KeyInfoFactory.java,v 1.12 2005/05/10 16:35:35 mullan Exp $
   27    */
   28   package javax.xml.crypto.dsig.keyinfo;
   29   
   30   import java.math.BigInteger;
   31   import java.security.KeyException;
   32   import java.security.NoSuchAlgorithmException;
   33   import java.security.NoSuchProviderException;
   34   import java.security.Provider;
   35   import java.security.PublicKey;
   36   import java.security.Security;
   37   import java.security.cert.X509CRL;
   38   import java.util.List;
   39   import javax.xml.crypto.MarshalException;
   40   import javax.xml.crypto.NoSuchMechanismException;
   41   import javax.xml.crypto.URIDereferencer;
   42   import javax.xml.crypto.XMLStructure;
   43   import javax.xml.crypto.dom.DOMStructure;
   44   import javax.xml.crypto.dsig;
   45   
   46   import sun.security.jca;
   47   import sun.security.jca.GetInstance.Instance;
   48   
   49   /**
   50    * A factory for creating {@link KeyInfo} objects from scratch or for
   51    * unmarshalling a <code>KeyInfo</code> object from a corresponding XML
   52    * representation.
   53    *
   54    * <p>Each instance of <code>KeyInfoFactory</code> supports a specific
   55    * XML mechanism type. To create a <code>KeyInfoFactory</code>, call one of the
   56    * static {@link #getInstance getInstance} methods, passing in the XML
   57    * mechanism type desired, for example:
   58    *
   59    * <blockquote><code>
   60    *   KeyInfoFactory factory = KeyInfoFactory.getInstance("DOM");
   61    * </code></blockquote>
   62    *
   63    * <p>The objects that this factory produces will be based
   64    * on DOM and abide by the DOM interoperability requirements as defined in the
   65    * <a href="../../../../../../technotes/guides/security/xmldsig/overview.html#DOM Mechanism Requirements">
   66    * DOM Mechanism Requirements</a> section of the API overview. See the
   67    * <a href="../../../../../../technotes/guides/security/xmldsig/overview.html#Service Provider">
   68    * Service Providers</a> section of the API overview for a list of standard
   69    * mechanism types.
   70    *
   71    * <p><code>KeyInfoFactory</code> implementations are registered and loaded
   72    * using the {@link java.security.Provider} mechanism.
   73    * For example, a service provider that supports the
   74    * DOM mechanism would be specified in the <code>Provider</code> subclass as:
   75    * <pre>
   76    *     put("KeyInfoFactory.DOM", "org.example.DOMKeyInfoFactory");
   77    * </pre>
   78    *
   79    * <p>Also, the <code>XMLStructure</code>s that are created by this factory
   80    * may contain state specific to the <code>KeyInfo</code> and are not
   81    * intended to be reusable.
   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>KeyInfoFactory</code>
   86    * instance to create the <code>XMLStructure</code>s of a particular
   87    * <code>KeyInfo</code> object. The behavior is undefined if
   88    * <code>XMLStructure</code>s from different providers or different mechanism
   89    * types are used together.
   90    *
   91    * <p><b>Concurrent Access</b>
   92    * <p>The static methods of this class are guaranteed to be thread-safe.
   93    * Multiple threads may concurrently invoke the static methods defined in this
   94    * class with no ill effects.
   95    *
   96    * <p>However, this is not true for the non-static methods defined by this
   97    * class. Unless otherwise documented by a specific provider, threads that
   98    * need to access a single <code>KeyInfoFactory</code> instance concurrently
   99    * should synchronize amongst themselves and provide the necessary locking.
  100    * Multiple threads each manipulating a different <code>KeyInfoFactory</code>
  101    * instance need not synchronize.
  102    *
  103    * @author Sean Mullan
  104    * @author JSR 105 Expert Group
  105    * @since 1.6
  106    */
  107   public abstract class KeyInfoFactory {
  108   
  109       private String mechanismType;
  110       private Provider provider;
  111   
  112       /**
  113        * Default constructor, for invocation by subclasses.
  114        */
  115       protected KeyInfoFactory() {}
  116   
  117       /**
  118        * Returns a <code>KeyInfoFactory</code> that supports the
  119        * specified XML processing mechanism and representation type (ex: "DOM").
  120        *
  121        * <p>This method uses the standard JCA provider lookup mechanism to
  122        * locate and instantiate a <code>KeyInfoFactory</code> implementation of
  123        * the desired mechanism type. It traverses the list of registered security
  124        * <code>Provider</code>s, starting with the most preferred
  125        * <code>Provider</code>. A new <code>KeyInfoFactory</code> object
  126        * from the first <code>Provider</code> that supports the specified
  127        * mechanism is returned.
  128        *
  129        * <p> Note that the list of registered providers may be retrieved via
  130        * the {@link Security#getProviders() Security.getProviders()} method.
  131        *
  132        * @param mechanismType the type of the XML processing mechanism and
  133        *    representation. See the <a
  134        *    href="../../../../../../technotes/guides/security/xmldsig/overview.html#Service Provider">
  135        *    Service Providers</a> section of the API overview for a list of
  136        *    standard mechanism types.
  137        * @return a new <code>KeyInfoFactory</code>
  138        * @throws NullPointerException if <code>mechanismType</code> is
  139        *    <code>null</code>
  140        * @throws NoSuchMechanismException if no <code>Provider</code> supports a
  141        *    <code>KeyInfoFactory</code> implementation for the specified mechanism
  142        * @see Provider
  143        */
  144       public static KeyInfoFactory getInstance(String mechanismType) {
  145           if (mechanismType == null) {
  146               throw new NullPointerException("mechanismType cannot be null");
  147           }
  148           Instance instance;
  149           try {
  150               instance = GetInstance.getInstance
  151                   ("KeyInfoFactory", null, mechanismType);
  152           } catch (NoSuchAlgorithmException nsae) {
  153               throw new NoSuchMechanismException(nsae);
  154           }
  155           KeyInfoFactory factory = (KeyInfoFactory) instance.impl;
  156           factory.mechanismType = mechanismType;
  157           factory.provider = instance.provider;
  158           return factory;
  159       }
  160   
  161       /**
  162        * Returns a <code>KeyInfoFactory</code> that supports the
  163        * requested XML processing mechanism and representation type (ex: "DOM"),
  164        * as supplied by the specified provider. Note that the specified
  165        * <code>Provider</code> object does not have to be registered in the
  166        * provider list.
  167        *
  168        * @param mechanismType the type of the XML processing mechanism and
  169        *    representation. See the <a
  170        *    href="../../../../../../technotes/guides/security/xmldsig/overview.html#Service Provider">
  171        *    Service Providers</a> section of the API overview for a list of
  172        *    standard mechanism types.
  173        * @param provider the <code>Provider</code> object
  174        * @return a new <code>KeyInfoFactory</code>
  175        * @throws NullPointerException if <code>mechanismType</code> or
  176        *    <code>provider</code> are <code>null</code>
  177        * @throws NoSuchMechanismException if a <code>KeyInfoFactory</code>
  178        *    implementation for the specified mechanism is not available from the
  179        *    specified <code>Provider</code> object
  180        * @see Provider
  181        */
  182       public static KeyInfoFactory getInstance(String mechanismType,
  183           Provider provider) {
  184           if (mechanismType == null) {
  185               throw new NullPointerException("mechanismType cannot be null");
  186           } else if (provider == null) {
  187               throw new NullPointerException("provider cannot be null");
  188           }
  189   
  190           Instance instance;
  191           try {
  192               instance = GetInstance.getInstance
  193                   ("KeyInfoFactory", null, mechanismType, provider);
  194           } catch (NoSuchAlgorithmException nsae) {
  195               throw new NoSuchMechanismException(nsae);
  196           }
  197           KeyInfoFactory factory = (KeyInfoFactory) instance.impl;
  198           factory.mechanismType = mechanismType;
  199           factory.provider = instance.provider;
  200           return factory;
  201       }
  202   
  203       /**
  204        * Returns a <code>KeyInfoFactory</code> that supports the
  205        * requested XML processing mechanism and representation type (ex: "DOM"),
  206        * as supplied by the specified provider. The specified provider must be
  207        * registered in the security provider list.
  208        *
  209        * <p>Note that the list of registered providers may be retrieved via
  210        * the {@link Security#getProviders() Security.getProviders()} method.
  211        *
  212        * @param mechanismType the type of the XML processing mechanism and
  213        *    representation. See the <a
  214        *    href="../../../../../../technotes/guides/security/xmldsig/overview.html#Service Provider">
  215        *    Service Providers</a> section of the API overview for a list of
  216        *    standard mechanism types.
  217        * @param provider the string name of the provider
  218        * @return a new <code>KeyInfoFactory</code>
  219        * @throws NoSuchProviderException if the specified provider is not
  220        *    registered in the security provider list
  221        * @throws NullPointerException if <code>mechanismType</code> or
  222        *    <code>provider</code> are <code>null</code>
  223        * @throws NoSuchMechanismException if a <code>KeyInfoFactory</code>
  224        *    implementation for the specified mechanism is not available from the
  225        *    specified provider
  226        * @see Provider
  227        */
  228       public static KeyInfoFactory getInstance(String mechanismType,
  229           String provider) throws NoSuchProviderException {
  230           if (mechanismType == null) {
  231               throw new NullPointerException("mechanismType cannot be null");
  232           } else if (provider == null) {
  233               throw new NullPointerException("provider cannot be null");
  234           } else if (provider.length() == 0) {
  235               throw new NoSuchProviderException();
  236           }
  237   
  238           Instance instance;
  239           try {
  240               instance = GetInstance.getInstance
  241                   ("KeyInfoFactory", null, mechanismType, provider);
  242           } catch (NoSuchAlgorithmException nsae) {
  243               throw new NoSuchMechanismException(nsae);
  244           }
  245           KeyInfoFactory factory = (KeyInfoFactory) instance.impl;
  246           factory.mechanismType = mechanismType;
  247           factory.provider = instance.provider;
  248           return factory;
  249       }
  250   
  251       /**
  252        * Returns a <code>KeyInfoFactory</code> that supports the
  253        * default XML processing mechanism and representation type ("DOM").
  254        *
  255        * <p>This method uses the standard JCA provider lookup mechanism to
  256        * locate and instantiate a <code>KeyInfoFactory</code> implementation of
  257        * the default mechanism type. It traverses the list of registered security
  258        * <code>Provider</code>s, starting with the most preferred
  259        * <code>Provider</code>.  A new <code>KeyInfoFactory</code> object
  260        * from the first <code>Provider</code> that supports the DOM mechanism is
  261        * returned.
  262        *
  263        * <p> Note that the list of registered providers may be retrieved via
  264        * the {@link Security#getProviders() Security.getProviders()} method.
  265        *
  266        * @return a new <code>KeyInfoFactory</code>
  267        * @throws NoSuchMechanismException if no <code>Provider</code> supports a
  268        *    <code>KeyInfoFactory</code> implementation for the DOM mechanism
  269        * @see Provider
  270        */
  271       public static KeyInfoFactory getInstance() {
  272           return getInstance("DOM");
  273       }
  274   
  275       /**
  276        * Returns the type of the XML processing mechanism and representation
  277        * supported by this <code>KeyInfoFactory</code> (ex: "DOM")
  278        *
  279        * @return the XML processing mechanism type supported by this
  280        *    <code>KeyInfoFactory</code>
  281        */
  282       public final String getMechanismType() {
  283           return mechanismType;
  284       }
  285   
  286       /**
  287        * Returns the provider of this <code>KeyInfoFactory</code>.
  288        *
  289        * @return the provider of this <code>KeyInfoFactory</code>
  290        */
  291       public final Provider getProvider() {
  292           return provider;
  293       }
  294   
  295       /**
  296        * Creates a <code>KeyInfo</code> containing the specified list of
  297        * key information types.
  298        *
  299        * @param content a list of one or more {@link XMLStructure}s representing
  300        *    key information types. The list is defensively copied to protect
  301        *    against subsequent modification.
  302        * @return a <code>KeyInfo</code>
  303        * @throws NullPointerException if <code>content</code> is <code>null</code>
  304        * @throws IllegalArgumentException if <code>content</code> is empty
  305        * @throws ClassCastException if <code>content</code> contains any entries
  306        *    that are not of type {@link XMLStructure}
  307        */
  308       public abstract KeyInfo newKeyInfo(List content);
  309   
  310       /**
  311        * Creates a <code>KeyInfo</code> containing the specified list of key
  312        * information types and optional id. The
  313        * <code>id</code> parameter represents the value of an XML
  314        * <code>ID</code> attribute and is useful for referencing
  315        * the <code>KeyInfo</code> from other XML structures.
  316        *
  317        * @param content a list of one or more {@link XMLStructure}s representing
  318        *    key information types. The list is defensively copied to protect
  319        *    against subsequent modification.
  320        * @param id the value of an XML <code>ID</code> (may be <code>null</code>)
  321        * @return a <code>KeyInfo</code>
  322        * @throws NullPointerException if <code>content</code> is <code>null</code>
  323        * @throws IllegalArgumentException if <code>content</code> is empty
  324        * @throws ClassCastException if <code>content</code> contains any entries
  325        *    that are not of type {@link XMLStructure}
  326        */
  327       public abstract KeyInfo newKeyInfo(List content, String id);
  328   
  329       /**
  330        * Creates a <code>KeyName</code> from the specified name.
  331        *
  332        * @param name the name that identifies the key
  333        * @return a <code>KeyName</code>
  334        * @throws NullPointerException if <code>name</code> is <code>null</code>
  335        */
  336       public abstract KeyName newKeyName(String name);
  337   
  338       /**
  339        * Creates a <code>KeyValue</code> from the specified public key.
  340        *
  341        * @param key the public key
  342        * @return a <code>KeyValue</code>
  343        * @throws KeyException if the <code>key</code>'s algorithm is not
  344        *    recognized or supported by this <code>KeyInfoFactory</code>
  345        * @throws NullPointerException if <code>key</code> is <code>null</code>
  346        */
  347       public abstract KeyValue newKeyValue(PublicKey key) throws KeyException;
  348   
  349       /**
  350        * Creates a <code>PGPData</code> from the specified PGP public key
  351        * identifier.
  352        *
  353        * @param keyId a PGP public key identifier as defined in <a href=
  354        *    "http://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a>, section 11.2.
  355        *    The array is cloned to protect against subsequent modification.
  356        * @return a <code>PGPData</code>
  357        * @throws NullPointerException if <code>keyId</code> is <code>null</code>
  358        * @throws IllegalArgumentException if the key id is not in the correct
  359        *    format
  360        */
  361       public abstract PGPData newPGPData(byte[] keyId);
  362   
  363       /**
  364        * Creates a <code>PGPData</code> from the specified PGP public key
  365        * identifier, and optional key material packet and list of external
  366        * elements.
  367        *
  368        * @param keyId a PGP public key identifier as defined in <a href=
  369        *    "http://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a>, section 11.2.
  370        *    The array is cloned to protect against subsequent modification.
  371        * @param keyPacket a PGP key material packet as defined in <a href=
  372        *    "http://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a>, section 5.5.
  373        *    The array is cloned to protect against subsequent modification. May
  374        *    be <code>null</code>.
  375        * @param other a list of {@link XMLStructure}s representing elements from
  376        *    an external namespace. The list is defensively copied to protect
  377        *    against subsequent modification. May be <code>null</code> or empty.
  378        * @return a <code>PGPData</code>
  379        * @throws NullPointerException if <code>keyId</code> is <code>null</code>
  380        * @throws IllegalArgumentException if the <code>keyId</code> or
  381        *    <code>keyPacket</code> is not in the correct format. For
  382        *    <code>keyPacket</code>, the format of the packet header is
  383        *    checked and the tag is verified that it is of type key material. The
  384        *    contents and format of the packet body are not checked.
  385        * @throws ClassCastException if <code>other</code> contains any
  386        *    entries that are not of type {@link XMLStructure}
  387        */
  388       public abstract PGPData newPGPData(byte[] keyId, byte[] keyPacket,
  389           List other);
  390   
  391       /**
  392        * Creates a <code>PGPData</code> from the specified PGP key material
  393        * packet and optional list of external elements.
  394        *
  395        * @param keyPacket a PGP key material packet as defined in <a href=
  396        *    "http://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a>, section 5.5.
  397        *    The array is cloned to protect against subsequent modification.
  398        * @param other a list of {@link XMLStructure}s representing elements from
  399        *    an external namespace. The list is defensively copied to protect
  400        *    against subsequent modification. May be <code>null</code> or empty.
  401        * @return a <code>PGPData</code>
  402        * @throws NullPointerException if <code>keyPacket</code> is
  403        *    <code>null</code>
  404        * @throws IllegalArgumentException if <code>keyPacket</code> is not in the
  405        *    correct format. For <code>keyPacket</code>, the format of the packet
  406        *    header is checked and the tag is verified that it is of type key
  407        *    material. The contents and format of the packet body are not checked.
  408        * @throws ClassCastException if <code>other</code> contains any
  409        *    entries that are not of type {@link XMLStructure}
  410        */
  411       public abstract PGPData newPGPData(byte[] keyPacket, List other);
  412   
  413       /**
  414        * Creates a <code>RetrievalMethod</code> from the specified URI.
  415        *
  416        * @param uri the URI that identifies the <code>KeyInfo</code> information
  417        *    to be retrieved
  418        * @return a <code>RetrievalMethod</code>
  419        * @throws NullPointerException if <code>uri</code> is <code>null</code>
  420        * @throws IllegalArgumentException if <code>uri</code> is not RFC 2396
  421        *    compliant
  422        */
  423       public abstract RetrievalMethod newRetrievalMethod(String uri);
  424   
  425       /**
  426        * Creates a <code>RetrievalMethod</code> from the specified parameters.
  427        *
  428        * @param uri the URI that identifies the <code>KeyInfo</code> information
  429        *    to be retrieved
  430        * @param type a URI that identifies the type of <code>KeyInfo</code>
  431        *    information to be retrieved (may be <code>null</code>)
  432        * @param transforms a list of {@link Transform}s. The list is defensively
  433        *    copied to protect against subsequent modification. May be
  434        *    <code>null</code> or empty.
  435        * @return a <code>RetrievalMethod</code>
  436        * @throws NullPointerException if <code>uri</code> is <code>null</code>
  437        * @throws IllegalArgumentException if <code>uri</code> is not RFC 2396
  438        *    compliant
  439        * @throws ClassCastException if <code>transforms</code> contains any
  440        *    entries that are not of type {@link Transform}
  441        */
  442       public abstract RetrievalMethod newRetrievalMethod(String uri, String type,
  443           List transforms);
  444   
  445       /**
  446        * Creates a <code>X509Data</code> containing the specified list of
  447        * X.509 content.
  448        *
  449        * @param content a list of one or more X.509 content types. Valid types are
  450        *    {@link String} (subject names), <code>byte[]</code> (subject key ids),
  451        *    {@link java.security.cert.X509Certificate}, {@link X509CRL},
  452        *    or {@link XMLStructure} ({@link X509IssuerSerial}
  453        *    objects or elements from an external namespace). Subject names are
  454        *    distinguished names in RFC 2253 String format. Implementations MUST
  455        *    support the attribute type keywords defined in RFC 2253 (CN, L, ST,
  456        *    O, OU, C, STREET, DC and UID). Implementations MAY support additional
  457        *    keywords. The list is defensively copied to protect against
  458        *    subsequent modification.
  459        * @return a <code>X509Data</code>
  460        * @throws NullPointerException if <code>content</code> is <code>null</code>
  461        * @throws IllegalArgumentException if <code>content</code> is empty, or
  462        *    if a subject name is not RFC 2253 compliant or one of the attribute
  463        *    type keywords is not recognized.
  464        * @throws ClassCastException if <code>content</code> contains any entries
  465        *    that are not of one of the valid types mentioned above
  466        */
  467       public abstract X509Data newX509Data(List content);
  468   
  469       /**
  470        * Creates an <code>X509IssuerSerial</code> from the specified X.500 issuer
  471        * distinguished name and serial number.
  472        *
  473        * @param issuerName the issuer's distinguished name in RFC 2253 String
  474        *    format. Implementations MUST support the attribute type keywords
  475        *    defined in RFC 2253 (CN, L, ST, O, OU, C, STREET, DC and UID).
  476        *    Implementations MAY support additional keywords.
  477        * @param serialNumber the serial number
  478        * @return an <code>X509IssuerSerial</code>
  479        * @throws NullPointerException if <code>issuerName</code> or
  480        *    <code>serialNumber</code> are <code>null</code>
  481        * @throws IllegalArgumentException if the issuer name is not RFC 2253
  482        *    compliant or one of the attribute type keywords is not recognized.
  483        */
  484       public abstract X509IssuerSerial newX509IssuerSerial
  485           (String issuerName, BigInteger serialNumber);
  486   
  487       /**
  488        * Indicates whether a specified feature is supported.
  489        *
  490        * @param feature the feature name (as an absolute URI)
  491        * @return <code>true</code> if the specified feature is supported,
  492        *    <code>false</code> otherwise
  493        * @throws NullPointerException if <code>feature</code> is <code>null</code>
  494        */
  495       public abstract boolean isFeatureSupported(String feature);
  496   
  497       /**
  498        * Returns a reference to the <code>URIDereferencer</code> that is used by
  499        * default to dereference URIs in {@link RetrievalMethod} objects.
  500        *
  501        * @return a reference to the default <code>URIDereferencer</code>
  502        */
  503       public abstract URIDereferencer getURIDereferencer();
  504   
  505       /**
  506        * Unmarshals a new <code>KeyInfo</code> instance from a
  507        * mechanism-specific <code>XMLStructure</code> (ex: {@link DOMStructure})
  508        * instance.
  509        *
  510        * @param xmlStructure a mechanism-specific XML structure from which to
  511        *   unmarshal the keyinfo from
  512        * @return the <code>KeyInfo</code>
  513        * @throws NullPointerException if <code>xmlStructure</code> is
  514        *   <code>null</code>
  515        * @throws ClassCastException if the type of <code>xmlStructure</code> is
  516        *   inappropriate for this factory
  517        * @throws MarshalException if an unrecoverable exception occurs during
  518        *   unmarshalling
  519        */
  520       public abstract KeyInfo unmarshalKeyInfo(XMLStructure xmlStructure)
  521           throws MarshalException;
  522   }

Home » openjdk-7 » javax » xml » crypto » dsig » keyinfo » [javadoc | source]