home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / main.bin / Signature.java < prev    next >
Text File  |  1997-10-01  |  22KB  |  597 lines

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