home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / security / Signature.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  20.3 KB  |  617 lines

  1. /*
  2.  * @(#)Signature.java    1.66 98/03/18
  3.  *
  4.  * Copyright 1996-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.   
  15. package java.security;
  16.  
  17. import java.security.spec.AlgorithmParameterSpec;
  18. import java.util.*;
  19. import java.io.*;
  20.  
  21. /**
  22.  * This Signature class is used to provide applications the functionality
  23.  * of a digital signature algorithm. Digital signatures are used for
  24.  * authentication and integrity assurance of digital data.
  25.  *
  26.  * <p> The signature algorithm can be, among others, the NIST standard
  27.  * DSA, using DSA and SHA-1. The DSA algorithm using the
  28.  * SHA-1 message digest algorithm can be specified, for example, as
  29.  * <tt>SHA/DSA</tt> or <tt>SHA-1/DSA</tt> (they are equivalent).
  30.  * In the case of RSA, there are multiple choices for the message digest
  31.  * algorithm, so the signing algorithm could be specified as, for example,
  32.  * <tt>MD2/RSA</tt>, <tt>MD5/RSA</tt>, or <tt>SHA-1/RSA</tt>.
  33.  * The algorithm name must be specified, as there is no default.
  34.  *
  35.  * <p>Like other algorithm-based classes in Java Security, Signature 
  36.  * provides implementation-independent algorithms, whereby a caller 
  37.  * (application code) requests a particular signature algorithm
  38.  * and is handed back a properly initialized Signature object. It is
  39.  * also possible, if desired, to request a particular algorithm from a
  40.  * particular provider. See the <code>getInstance </code> methods.
  41.  *
  42.  * <p>Thus, there are two ways to request a Signature algorithm object: by
  43.  * specifying either just an algorithm name, or both an algorithm name
  44.  * and a package provider. <ul>
  45.  *
  46.  * <li>If just an algorithm name is specified, the system will
  47.  * determine if there is an implementation of the algorithm requested
  48.  * available in the environment, and if there is more than one, if
  49.  * there is a preferred one.<p>
  50.  * 
  51.  * <li>If both an algorithm name and a package provider are specified,
  52.  * the system will determine if there is an implementation of the
  53.  * algorithm in the package requested, and throw an exception if there
  54.  * is not.
  55.  *
  56.  * </ul>
  57.  *
  58.  * <p>A Signature object can be used to generate and verify digital
  59.  * signatures.
  60.  *
  61.  * <p>There are three phases to the use of a Signature object for
  62.  * either signing data or verifying a signature:<ol>
  63.  *
  64.  * <li>Initialization, with either 
  65.  *
  66.  *     <ul>
  67.  *
  68.  *     <li>a public key, which initializes the signature for
  69.  *     verification (see <a href = "#initVerify">initVerify</a>), or
  70.  *
  71.  *     <li>a private key (and optionally a Secure Random Number Generator),
  72.  *     which initializes the signature for signing
  73.  *     (see <a href = "#initSign">initSign</a>).
  74.  *
  75.  *     </ul><p>
  76.  *
  77.  * <li>Updating<p>
  78.  *
  79.  * <p>Depending on the type of initialization, this will update the
  80.  * bytes to be signed or verified. See the <a href =
  81.  * "#update(byte)">update</a> methods.<p>
  82.  *
  83.  * <li>Signing or Verifying a signature on all updated bytes. See <a
  84.  * href = "#sign">sign</a> and <a href = "#verify">verify</a>.
  85.  *
  86.  * </ol>
  87.  *
  88.  * <p>Note that this class is abstract and extends from
  89.  * <code>SignatureSpi</code> for historical reasons.
  90.  * Application developers should only take notice of the methods defined in
  91.  * this <code>Signature</code> class, and ignore all the methods in
  92.  * the superclass.
  93.  *
  94.  * @author Benjamin Renaud 
  95.  *
  96.  * @version 1.66 98/03/18
  97.  */
  98.  
  99. public abstract class Signature extends SignatureSpi {
  100.  
  101.     /*  Are we in debugging mode? */
  102.     private static final boolean debug = false;
  103.  
  104.     /*
  105.      * The algorithm for this signature object.
  106.      * This value is used to map an OID to the particular algorithm.
  107.      * The mapping is done in AlgorithmObject.algOID(String algorithm)
  108.      */
  109.     private String algorithm;
  110.  
  111.     // The provider
  112.     private Provider provider;
  113.  
  114.     /** 
  115.      * Possible <a href = "#state ">state </a> value, signifying that       
  116.      * this signature object has not yet been initialized.
  117.      */      
  118.     protected final static int UNINITIALIZED = 0;       
  119.        
  120.     /** 
  121.      * Possible <a href = "#state ">state </a> value, signifying that       
  122.      * this signature object has been initialized for signing.
  123.      */      
  124.     protected final static int SIGN = 2;
  125.        
  126.     /** 
  127.      * Possible <a href = "#state ">state </a> value, signifying that       
  128.      * this signature object has been initialized for verification.
  129.      */      
  130.     protected final static int VERIFY = 3;
  131.  
  132.     /** 
  133.      * Current state of this signature object.
  134.      */      
  135.     protected int state = UNINITIALIZED;
  136.  
  137.     /**
  138.      * Creates a Signature object for the specified algorithm.
  139.      *
  140.      * @param algorithm the standard string name of the algorithm. 
  141.      * See Appendix A in the <a href=
  142.      * "../guide/security/CryptoSpec.html#AppA">
  143.      * Java Cryptography Architecture API Specification & Reference </a> 
  144.      * for information about standard algorithm names.
  145.      */
  146.     protected Signature(String algorithm) {
  147.     this.algorithm = algorithm;
  148.     }
  149.  
  150.     /**
  151.      * Generates a Signature object that implements the specified digest
  152.      * algorithm. If the default provider package
  153.      * provides an implementation of the requested digest algorithm,
  154.      * an instance of Signature containing that implementation is returned.
  155.      * If the algorithm is not available in the default 
  156.      * package, other packages are searched.
  157.      *
  158.      * @param algorithm the standard name of the algorithm requested. 
  159.      * See Appendix A in the <a href=
  160.      * "../guide/security/CryptoSpec.html#AppA">
  161.      * Java Cryptography Architecture API Specification & Reference </a> 
  162.      * for information about standard algorithm names.
  163.      *
  164.      * @return the new Signature object.
  165.      *
  166.      * @exception NoSuchAlgorithmException if the algorithm is
  167.      * not available in the environment.
  168.      */
  169.     public static Signature getInstance(String algorithm) 
  170.     throws NoSuchAlgorithmException {
  171.     if (algorithm.equalsIgnoreCase("DSA"))
  172.         algorithm = new String("SHA/DSA");
  173.     try {
  174.         Object[] objs = Security.getImpl(algorithm, "Signature", null);
  175.         if (objs[0] instanceof Signature) {
  176.         Signature sig = (Signature)objs[0];
  177.         sig.provider = (Provider)objs[1];
  178.         return sig;
  179.         } else {
  180.         Delegate delegate = new Delegate((SignatureSpi)objs[0],
  181.                          algorithm);
  182.         delegate.provider = (Provider)objs[1];
  183.         return delegate;
  184.         }
  185.     } catch(NoSuchProviderException e) {
  186.         throw new NoSuchAlgorithmException(algorithm + " not found");
  187.     }
  188.     }
  189.  
  190.     /** 
  191.      * Generates a Signature object implementing the specified
  192.      * algorithm, as supplied from the specified provider, if such an 
  193.      * algorithm is available from the provider.
  194.      *
  195.      * @param algorithm the name of the algorithm requested.
  196.      * See Appendix A in the <a href=
  197.      * "../guide/security/CryptoSpec.html#AppA">
  198.      * Java Cryptography Architecture API Specification & Reference </a> 
  199.      * for information about standard algorithm names.
  200.      *
  201.      * @param provider the name of the provider.
  202.      *
  203.      * @return the new Signature object.
  204.      *
  205.      * @exception NoSuchAlgorithmException if the algorithm is
  206.      * not available in the package supplied by the requested
  207.      * provider.
  208.      *
  209.      * @exception NoSuchProviderException if the provider is not
  210.      * available in the environment. 
  211.      * 
  212.      * @see Provider 
  213.      */
  214.     public static Signature getInstance(String algorithm, String provider) 
  215.     throws NoSuchAlgorithmException, NoSuchProviderException {
  216.     if (algorithm.equalsIgnoreCase("DSA"))
  217.         algorithm = new String("SHA/DSA");
  218.     Object[] objs = Security.getImpl(algorithm, "Signature", provider);
  219.     if (objs[0] instanceof Signature) {
  220.         Signature sig = (Signature)objs[0];
  221.         sig.provider = (Provider)objs[1];
  222.         return sig;
  223.     } else {
  224.         Delegate delegate = new Delegate((SignatureSpi)objs[0], algorithm);
  225.         delegate.provider = (Provider)objs[1];
  226.         return delegate;
  227.     }
  228.     }
  229.  
  230.     /** 
  231.      * Returns the provider of this signature object.
  232.      * 
  233.      * @return the provider of this signature object
  234.      */
  235.     public final Provider getProvider() {
  236.     return this.provider;
  237.     }
  238.  
  239.     /**
  240.      * Initializes this object for verification. If this method is called
  241.      * again with a different argument, it negates the effect
  242.      * of this call.
  243.      *
  244.      * @param publicKey the public key of the identity whose signature is
  245.      * going to be verified.
  246.      *
  247.      * @exception InvalidKeyException if the key is invalid.
  248.      */
  249.     public final void initVerify(PublicKey publicKey) 
  250.     throws InvalidKeyException {
  251.         engineInitVerify(publicKey);
  252.         state = VERIFY;
  253.     }
  254.  
  255.     /**
  256.      * Initialize this object for signing. If this method is called
  257.      * again with a different argument, it negates the effect
  258.      * of this call.
  259.      *
  260.      * @param privateKey the private key of the identity whose signature
  261.      * is going to be generated.
  262.      * 
  263.      * @exception InvalidKeyException if the key is invalid.  
  264.      */
  265.     public final void initSign(PrivateKey privateKey) 
  266.     throws InvalidKeyException {
  267.         engineInitSign(privateKey);
  268.         state = SIGN;
  269.     }
  270.  
  271.     /**
  272.      * Initialize this object for signing. If this method is called
  273.      * again with a different argument, it negates the effect
  274.      * of this call.
  275.      *
  276.      * @param privateKey the private key of the identity whose signature
  277.      * is going to be generated.
  278.      * 
  279.      * @param random the source of randomness for this signature.
  280.      * 
  281.      * @exception InvalidKeyException if the key is invalid.  
  282.      */
  283.     public final void initSign(PrivateKey privateKey, SecureRandom random) 
  284.     throws InvalidKeyException {
  285.         engineInitSign(privateKey, random);
  286.         state = SIGN;
  287.     }
  288.  
  289.     /**
  290.      * Returns the signature bytes of all the data updated.  The 
  291.      * signature returned is X.509-encoded. 
  292.      * 
  293.      * <p>A call to this method resets this signature object to the state 
  294.      * it was in when previously initialized for signing via a
  295.      * call to <code>initSign(PrivateKey)</code>. That is, the object is 
  296.      * reset and available to generate another signature from the same 
  297.      * signer, if desired, via new calls to <code>update</code> and 
  298.      * <code>sign</code>.     
  299.      *
  300.      * @return the signature bytes of the signing operation's result.
  301.      *
  302.      * @exception SignatureException if this signature object is not
  303.      * initialized properly.
  304.      */
  305.     public final byte[] sign() throws SignatureException {
  306.     if (state == SIGN) {
  307.         return engineSign();
  308.     }
  309.     throw new SignatureException("object not initialized for " +
  310.                      "signing");
  311.     }
  312.  
  313.     /**
  314.      * Verifies the passed-in signature. The signature bytes are expected 
  315.      * to be X.509-encoded. 
  316.      * 
  317.      * <p>A call to this method resets this signature object to the state 
  318.      * it was in when previously initialized for verification via a
  319.      * call to <code>initVerify(PublicKey)</code>. That is, the object is 
  320.      * reset and available to verify another signature from the identity
  321.      * whose public key was specified in the call to <code>initVerify</code>.
  322.      *      
  323.      * @param signature the signature bytes to be verified.
  324.      *
  325.      * @return true if the signature was verified, false if not. 
  326.      *
  327.      * @exception SignatureException if this signature object is not 
  328.      * initialized properly, or the passed-in signature is improperly 
  329.      * encoded or of the wrong type, etc.  
  330.      */
  331.     public final boolean verify(byte[] signature) throws SignatureException {
  332.     if (state == VERIFY) {
  333.         return engineVerify(signature);
  334.     }
  335.     throw new SignatureException("object not initialized for " +
  336.                      "verification");
  337.     }
  338.  
  339.     /**
  340.      * Updates the data to be signed or verified by a byte.
  341.      *
  342.      * @param b the byte to use for the update.
  343.      * 
  344.      * @exception SignatureException if this signature object is not 
  345.      * initialized properly.     
  346.      */
  347.     public final void update(byte b) throws SignatureException {
  348.     if (state == VERIFY || state == SIGN) {
  349.         engineUpdate(b);
  350.     } else {
  351.         throw new SignatureException("object not initialized for "
  352.                      + "signature or verification");
  353.     }
  354.     }
  355.  
  356.     /**
  357.      * Updates the data to be signed or verified, using the specified
  358.      * array of bytes.
  359.      *
  360.      * @param data the byte array to use for the update.       
  361.      * 
  362.      * @exception SignatureException if this signature object is not 
  363.      * initialized properly.          
  364.      */
  365.     public final void update(byte[] data) throws SignatureException {
  366.     update(data, 0, data.length);
  367.     }
  368.  
  369.     /**
  370.      * Updates the data to be signed or verified, using the specified
  371.      * array of bytes, starting at the specified offset.  
  372.      *
  373.      * @param data the array of bytes.  
  374.      * @param off the offset to start from in the array of bytes.  
  375.      * @param len the number of bytes to use, starting at offset.
  376.      *  
  377.      * @exception SignatureException if this signature object is not 
  378.      * initialized properly.          
  379.      */
  380.     public final void update(byte[] data, int off, int len) 
  381.     throws SignatureException {
  382.         if (state == SIGN || state == VERIFY) {
  383.         engineUpdate(data, off, len);
  384.         } else {
  385.         throw new SignatureException("object not initialized for "
  386.                          + "signature or verification");
  387.         }
  388.     }
  389.  
  390.     /** 
  391.      * Returns the name of the algorithm for this signature object.
  392.      * 
  393.      * @return the name of the algorithm for this signature object.
  394.      */
  395.     public final String getAlgorithm() {
  396.     return this.algorithm;
  397.     }
  398.  
  399.     /**
  400.      * Returns a string representation of this signature object,       
  401.      * providing information that includes the state of the object       
  402.      * and the name of the algorithm used.       
  403.      * 
  404.      * @return a string representation of this signature object.
  405.      */
  406.     public String toString() {
  407.     String initState = "";
  408.     switch (state) {
  409.     case UNINITIALIZED:
  410.         initState = "<not initialized>";
  411.         break;
  412.       case VERIFY:
  413.         initState = "<initialized for verifying>";
  414.         break;          
  415.       case SIGN:
  416.         initState = "<initialized for signing>";
  417.         break;          
  418.     }
  419.     return "Signature object: " + getAlgorithm() + initState;
  420.     }
  421.  
  422.     /**
  423.      * Sets the specified algorithm parameter to the specified value.
  424.      * This method supplies a general-purpose mechanism through
  425.      * which it is possible to set the various parameters of this object. 
  426.      * A parameter may be any settable parameter for the algorithm, such as 
  427.      * a parameter size, or a source of random bits for signature generation 
  428.      * (if appropriate), or an indication of whether or not to perform
  429.      * a specific but optional computation. A uniform algorithm-specific 
  430.      * naming scheme for each parameter is desirable but left unspecified 
  431.      * at this time.
  432.      *
  433.      * @param param the string identifier of the parameter.
  434.      * @param value the parameter value.
  435.      *
  436.      * @exception InvalidParameterException if <code>param</code> is an
  437.      * invalid parameter for this signature algorithm engine,
  438.      * the parameter is already set
  439.      * and cannot be set again, a security exception occurs, and so on.
  440.      *
  441.      * @deprecated Use <a href = "#setParameter(AlgorithmParameterSpec)">
  442.      * setParameter</a>.
  443.      */
  444.     public final void setParameter(String param, Object value) 
  445.     throws InvalidParameterException {
  446.         engineSetParameter(param, value);
  447.     }
  448.  
  449.     /**
  450.      * Initializes this signature engine with the specified parameter set.
  451.      *
  452.      * @param params the parameters
  453.      *
  454.      * @exception InvalidAlgorithmParameterException if the given parameters
  455.      * are inappropriate for this signature engine
  456.      */
  457.     public final void setParameter(AlgorithmParameterSpec params)
  458.     throws InvalidAlgorithmParameterException {
  459.         engineSetParameter(params);
  460.     }
  461.  
  462.     /**
  463.      * Gets the value of the specified algorithm parameter. This method 
  464.      * supplies a general-purpose mechanism through which it is possible to 
  465.      * get the various parameters of this object. A parameter may be any 
  466.      * settable parameter for the algorithm, such as a parameter size, or 
  467.      * a source of random bits for signature generation (if appropriate), 
  468.      * or an indication of whether or not to perform a specific but optional 
  469.      * computation. A uniform algorithm-specific naming scheme for each 
  470.      * parameter is desirable but left unspecified at this time.
  471.      *
  472.      * @param param the string name of the parameter.
  473.      *
  474.      * @return the object that represents the parameter value, or null if
  475.      * there is none.
  476.      *
  477.      * @exception InvalidParameterException if <code>param</code> is an invalid
  478.      * parameter for this engine, or another exception occurs while
  479.      * trying to get this parameter.
  480.      *
  481.      * @deprecated
  482.      */
  483.     public final Object getParameter(String param) 
  484.     throws InvalidParameterException {
  485.         return engineGetParameter(param);
  486.     }
  487.  
  488.     /**
  489.      * Returns a clone if the implementation is cloneable.
  490.      * 
  491.      * @return a clone if the implementation is cloneable.
  492.      *
  493.      * @exception CloneNotSupportedException if this is called
  494.      * on an implementation that does not support <code>Cloneable</code>.
  495.      */
  496.     public Object clone() throws CloneNotSupportedException {
  497.     if (this instanceof Cloneable) {
  498.         return super.clone();
  499.     } else {
  500.         throw new CloneNotSupportedException();
  501.     }
  502.     }
  503.  
  504.     // private debugging method.
  505.     private static void debug(String statement) {
  506.     if (debug) {
  507.         System.err.println(statement);
  508.     }
  509.     }
  510.  
  511.     // private debugging method.
  512.     private static void debug(Exception e) {
  513.     if (debug) {
  514.         e.printStackTrace();
  515.     }
  516.     }
  517.  
  518.  
  519.  
  520.  
  521.     /*
  522.      * The following class allows providers to extend from SignatureSpi
  523.      * rather than from Signature. It represents a Signature with an
  524.      * encapsulated, provider-supplied SPI object (of type SignatureSpi).
  525.      * If the provider implementation is an instance of SignatureSpi, the
  526.      * getInstance() methods above return an instance of this class, with
  527.      * the SPI object encapsulated.
  528.      *
  529.      * Note: All SPI methods from the original Signature class have been
  530.      * moved up the hierarchy into a new class (SignatureSpi), which has
  531.      * been interposed in the hierarchy between the API (Signature)
  532.      * and its original parent (Object).
  533.      */
  534.  
  535.     static class Delegate extends Signature {
  536.  
  537.     // The provider implementation (delegate)
  538.     private SignatureSpi sigSpi;
  539.  
  540.     // constructor
  541.     public Delegate(SignatureSpi sigSpi, String algorithm) {
  542.         super(algorithm);
  543.         this.sigSpi = sigSpi;
  544.     }
  545.  
  546.     /*
  547.      * Returns a clone if the delegate is cloneable.    
  548.      * 
  549.      * @return a clone if the delegate is cloneable.
  550.      *
  551.      * @exception CloneNotSupportedException if this is called on a
  552.      * delegate that does not support <code>Cloneable</code>.
  553.      */
  554.     public Object clone() throws CloneNotSupportedException {
  555.         if (sigSpi instanceof Cloneable) {
  556.         SignatureSpi sigSpiClone = (SignatureSpi)sigSpi.clone();
  557.         Delegate that = new Delegate(sigSpiClone, algorithm);
  558.         that.provider = provider;
  559.         return that;
  560.         } else {
  561.         throw new CloneNotSupportedException();
  562.         }
  563.     }
  564.  
  565.     protected void engineInitVerify(PublicKey publicKey)
  566.         throws InvalidKeyException {
  567.         sigSpi.engineInitVerify(publicKey);
  568.     }
  569.  
  570.     protected void engineInitSign(PrivateKey privateKey)
  571.         throws InvalidKeyException {
  572.         sigSpi.engineInitSign(privateKey);
  573.     }
  574.  
  575.     protected void engineUpdate(byte b) throws SignatureException {
  576.         sigSpi.engineUpdate(b);
  577.     }
  578.  
  579.     protected void engineUpdate(byte[] b, int off, int len) 
  580.         throws SignatureException {
  581.         sigSpi.engineUpdate(b, off, len);
  582.     }
  583.     
  584.     protected byte[] engineSign() throws SignatureException {
  585.         return sigSpi.engineSign();
  586.     }
  587.  
  588.     protected boolean engineVerify(byte[] sigBytes) 
  589.         throws SignatureException {
  590.         return sigSpi.engineVerify(sigBytes);
  591.     }
  592.  
  593.     protected void engineSetParameter(String param, Object value) 
  594.         throws InvalidParameterException {
  595.         sigSpi.engineSetParameter(param, value);
  596.     }
  597.  
  598.     protected void engineSetParameter(AlgorithmParameterSpec params)
  599.         throws InvalidAlgorithmParameterException {
  600.         sigSpi.engineSetParameter(params);
  601.     }
  602.  
  603.     protected Object engineGetParameter(String param)
  604.         throws InvalidParameterException {
  605.         return sigSpi.engineGetParameter(param);
  606.     }
  607.     }
  608. }
  609.     
  610.         
  611.  
  612.  
  613.  
  614.         
  615.         
  616.     
  617.