home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / security / Signature.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  22.5 KB  |  678 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)Signature.java    1.76 98/07/17
  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 {@link initVerify(PublicKey) initVerify}), or
  70.  *
  71.  *     <li>a private key (and optionally a Secure Random Number Generator),
  72.  *     which initializes the signature for signing
  73.  *     (see {@link initSign(PrivateKey)}
  74.  *     and <a href = 
  75.  *     "#initSign(java.security.PrivateKey, java.security.SecureRandom)">
  76.  *     initSign(PrivateKey, SecureRandom)</a>).
  77.  *
  78.  *     </ul><p>
  79.  *
  80.  * <li>Updating<p>
  81.  *
  82.  * <p>Depending on the type of initialization, this will update the
  83.  * bytes to be signed or verified. See the 
  84.  * {@link update(byte) update} methods.<p>
  85.  *
  86.  * <li>Signing or Verifying a signature on all updated bytes. See the 
  87.  * {@link sign() sign} methods and the {@link verify(byte[]) verify}
  88.  * method.
  89.  *
  90.  * </ol>
  91.  *
  92.  * <p>Note that this class is abstract and extends from
  93.  * <code>SignatureSpi</code> for historical reasons.
  94.  * Application developers should only take notice of the methods defined in
  95.  * this <code>Signature</code> class; all the methods in
  96.  * the superclass are intended for cryptographic service providers who wish to
  97.  * supply their own implementations of digital signature algorithms.
  98.  *
  99.  * @author Benjamin Renaud 
  100.  *
  101.  * @version 1.76 99/03/26
  102.  */
  103.  
  104. public abstract class Signature extends SignatureSpi {
  105.  
  106.     /*  Are we in debugging mode? */
  107.     private static final boolean debug = false;
  108.  
  109.     /*
  110.      * The algorithm for this signature object.
  111.      * This value is used to map an OID to the particular algorithm.
  112.      * The mapping is done in AlgorithmObject.algOID(String algorithm)
  113.      */
  114.     private String algorithm;
  115.  
  116.     // The provider
  117.     private Provider provider;
  118.  
  119.     /** 
  120.      * Possible <a href = "#state ">state </a> value, signifying that       
  121.      * this signature object has not yet been initialized.
  122.      */      
  123.     protected final static int UNINITIALIZED = 0;       
  124.        
  125.     /** 
  126.      * Possible <a href = "#state ">state </a> value, signifying that       
  127.      * this signature object has been initialized for signing.
  128.      */      
  129.     protected final static int SIGN = 2;
  130.        
  131.     /** 
  132.      * Possible <a href = "#state ">state </a> value, signifying that       
  133.      * this signature object has been initialized for verification.
  134.      */      
  135.     protected final static int VERIFY = 3;
  136.  
  137.     /** 
  138.      * Current state of this signature object.
  139.      */      
  140.     protected int state = UNINITIALIZED;
  141.  
  142.     /**
  143.      * Creates a Signature object for the specified algorithm.
  144.      *
  145.      * @param algorithm the standard string name of the algorithm. 
  146.      * See Appendix A in the <a href=
  147.      * "../../../guide/security/CryptoSpec.html#AppA">
  148.      * Java Cryptography Architecture API Specification & Reference </a> 
  149.      * for information about standard algorithm names.
  150.      */
  151.     protected Signature(String algorithm) {
  152.     this.algorithm = algorithm;
  153.     }
  154.  
  155.     /**
  156.      * Generates a Signature object that implements the specified digest
  157.      * algorithm. If the default provider package
  158.      * provides an implementation of the requested digest algorithm,
  159.      * an instance of Signature containing that implementation is returned.
  160.      * If the algorithm is not available in the default 
  161.      * package, other packages are searched.
  162.      *
  163.      * @param algorithm the standard name of the algorithm requested. 
  164.      * See Appendix A in the <a href=
  165.      * "../../../guide/security/CryptoSpec.html#AppA">
  166.      * Java Cryptography Architecture API Specification & Reference </a> 
  167.      * for information about standard algorithm names.
  168.      *
  169.      * @return the new Signature object.
  170.      *
  171.      * @exception NoSuchAlgorithmException if the algorithm is
  172.      * not available in the environment.
  173.      */
  174.     public static Signature getInstance(String algorithm) 
  175.     throws NoSuchAlgorithmException {
  176.     if (algorithm.equalsIgnoreCase("DSA"))
  177.         algorithm = new String("SHA/DSA");
  178.     try {
  179.         Object[] objs = Security.getImpl(algorithm, "Signature", null);
  180.         if (objs[0] instanceof Signature) {
  181.         Signature sig = (Signature)objs[0];
  182.         sig.provider = (Provider)objs[1];
  183.         return sig;
  184.         } else {
  185.         Signature delegate =
  186.             new Delegate((SignatureSpi)objs[0], algorithm);
  187.         delegate.provider = (Provider)objs[1];
  188.         return delegate;
  189.         }
  190.     } catch(NoSuchProviderException e) {
  191.         throw new NoSuchAlgorithmException(algorithm + " not found");
  192.     }
  193.     }
  194.  
  195.     /** 
  196.      * Generates a Signature object implementing the specified
  197.      * algorithm, as supplied from the specified provider, if such an 
  198.      * algorithm is available from the provider.
  199.      *
  200.      * @param algorithm the name of the algorithm requested.
  201.      * See Appendix A in the <a href=
  202.      * "../../../guide/security/CryptoSpec.html#AppA">
  203.      * Java Cryptography Architecture API Specification & Reference </a> 
  204.      * for information about standard algorithm names.
  205.      *
  206.      * @param provider the name of the provider.
  207.      *
  208.      * @return the new Signature object.
  209.      *
  210.      * @exception NoSuchAlgorithmException if the algorithm is
  211.      * not available in the package supplied by the requested
  212.      * provider.
  213.      *
  214.      * @exception NoSuchProviderException if the provider is not
  215.      * available in the environment. 
  216.      * 
  217.      * @see Provider 
  218.      */
  219.     public static Signature getInstance(String algorithm, String provider) 
  220.     throws NoSuchAlgorithmException, NoSuchProviderException
  221.     {
  222.     if (provider == null || provider.length() == 0)
  223.         throw new IllegalArgumentException("missing provider");
  224.     if (algorithm.equalsIgnoreCase("DSA"))
  225.         algorithm = new String("SHA/DSA");
  226.     Object[] objs = Security.getImpl(algorithm, "Signature", provider);
  227.     if (objs[0] instanceof Signature) {
  228.         Signature sig = (Signature)objs[0];
  229.         sig.provider = (Provider)objs[1];
  230.         return sig;
  231.     } else {
  232.         Signature delegate =
  233.         new Delegate((SignatureSpi)objs[0], algorithm);
  234.         delegate.provider = (Provider)objs[1];
  235.         return delegate;
  236.     }
  237.     }
  238.  
  239.     /** 
  240.      * Returns the provider of this signature object.
  241.      * 
  242.      * @return the provider of this signature object
  243.      */
  244.     public final Provider getProvider() {
  245.     return this.provider;
  246.     }
  247.  
  248.     /**
  249.      * Initializes this object for verification. If this method is called
  250.      * again with a different argument, it negates the effect
  251.      * of this call.
  252.      *
  253.      * @param publicKey the public key of the identity whose signature is
  254.      * going to be verified.
  255.      *
  256.      * @exception InvalidKeyException if the key is invalid.
  257.      */
  258.     public final void initVerify(PublicKey publicKey) 
  259.     throws InvalidKeyException {
  260.         engineInitVerify(publicKey);
  261.         state = VERIFY;
  262.     }
  263.  
  264.     /**
  265.      * Initialize this object for signing. If this method is called
  266.      * again with a different argument, it negates the effect
  267.      * of this call.
  268.      *
  269.      * @param privateKey the private key of the identity whose signature
  270.      * is going to be generated.
  271.      * 
  272.      * @exception InvalidKeyException if the key is invalid.  
  273.      */
  274.     public final void initSign(PrivateKey privateKey) 
  275.     throws InvalidKeyException {
  276.         engineInitSign(privateKey);
  277.         state = SIGN;
  278.     }
  279.  
  280.     /**
  281.      * Initialize this object for signing. If this method is called
  282.      * again with a different argument, it negates the effect
  283.      * of this call.
  284.      *
  285.      * @param privateKey the private key of the identity whose signature
  286.      * is going to be generated.
  287.      * 
  288.      * @param random the source of randomness for this signature.
  289.      * 
  290.      * @exception InvalidKeyException if the key is invalid.  
  291.      */
  292.     public final void initSign(PrivateKey privateKey, SecureRandom random) 
  293.     throws InvalidKeyException {
  294.         engineInitSign(privateKey, random);
  295.         state = SIGN;
  296.     }
  297.  
  298.     /**
  299.      * Returns the signature bytes of all the data updated.
  300.      * The format of the signature depends on the underlying 
  301.      * signature scheme.
  302.      * 
  303.      * <p>A call to this method resets this signature object to the state 
  304.      * it was in when previously initialized for signing via a
  305.      * call to <code>initSign(PrivateKey)</code>. That is, the object is 
  306.      * reset and available to generate another signature from the same 
  307.      * signer, if desired, via new calls to <code>update</code> and 
  308.      * <code>sign</code>.     
  309.      *
  310.      * @return the signature bytes of the signing operation's result.
  311.      *
  312.      * @exception SignatureException if this signature object is not
  313.      * initialized properly.
  314.      */
  315.     public final byte[] sign() throws SignatureException {
  316.     if (state == SIGN) {
  317.         return engineSign();
  318.     }
  319.     throw new SignatureException("object not initialized for " +
  320.                      "signing");
  321.     }
  322.  
  323.     /**
  324.      * Finishes the signature operation and stores the resulting signature
  325.      * bytes in the provided buffer <code>outbuf</code>, starting at
  326.      * <code>offset</code>. 
  327.      * The format of the signature depends on the underlying 
  328.      * signature scheme.
  329.      * 
  330.      * <p>This signature object is reset to its initial state (the state it
  331.      * was in after a call to one of the <code>initSign</code> methods) and
  332.      * can be reused to generate further signatures with the same private key.
  333.      *
  334.      * @param outbuf buffer for the signature result.
  335.      *
  336.      * @param offset offset into <code>outbuf</code> where the signature is
  337.      * stored.
  338.      *
  339.      * @param len number of bytes within <code>outbuf</code> allotted for the
  340.      * signature.
  341.      *
  342.      * @return the number of bytes placed into <code>outbuf</code>.
  343.      *
  344.      * @exception SignatureException if an error occurs or <code>len</code>
  345.      * is less than the actual signature length.
  346.      *
  347.      * @since JDK1.2
  348.      */
  349.     public final int sign(byte[] outbuf, int offset, int len)
  350.     throws SignatureException {
  351.     if (outbuf == null) {
  352.         throw new IllegalArgumentException("No output buffer given");
  353.     }
  354.     if (outbuf.length - offset < len) {
  355.         throw new IllegalArgumentException
  356.         ("Output buffer too small for specified offset and length");
  357.     }
  358.     if (state != SIGN) {
  359.         throw new SignatureException("object not initialized for " +
  360.                      "signing");
  361.     }
  362.     return engineSign(outbuf, offset, len);
  363.     }
  364.  
  365.     /**
  366.      * Verifies the passed-in signature. 
  367.      * 
  368.      * <p>A call to this method resets this signature object to the state 
  369.      * it was in when previously initialized for verification via a
  370.      * call to <code>initVerify(PublicKey)</code>. That is, the object is 
  371.      * reset and available to verify another signature from the identity
  372.      * whose public key was specified in the call to <code>initVerify</code>.
  373.      *      
  374.      * @param signature the signature bytes to be verified.
  375.      *
  376.      * @return true if the signature was verified, false if not. 
  377.      *
  378.      * @exception SignatureException if this signature object is not 
  379.      * initialized properly, or the passed-in signature is improperly 
  380.      * encoded or of the wrong type, etc.  
  381.      */
  382.     public final boolean verify(byte[] signature) throws SignatureException {
  383.     if (state == VERIFY) {
  384.         return engineVerify(signature);
  385.     }
  386.     throw new SignatureException("object not initialized for " +
  387.                      "verification");
  388.     }
  389.  
  390.     /**
  391.      * Updates the data to be signed or verified by a byte.
  392.      *
  393.      * @param b the byte to use for the update.
  394.      * 
  395.      * @exception SignatureException if this signature object is not 
  396.      * initialized properly.     
  397.      */
  398.     public final void update(byte b) throws SignatureException {
  399.     if (state == VERIFY || state == SIGN) {
  400.         engineUpdate(b);
  401.     } else {
  402.         throw new SignatureException("object not initialized for "
  403.                      + "signature or verification");
  404.     }
  405.     }
  406.  
  407.     /**
  408.      * Updates the data to be signed or verified, using the specified
  409.      * array of bytes.
  410.      *
  411.      * @param data the byte array to use for the update.       
  412.      * 
  413.      * @exception SignatureException if this signature object is not 
  414.      * initialized properly.          
  415.      */
  416.     public final void update(byte[] data) throws SignatureException {
  417.     update(data, 0, data.length);
  418.     }
  419.  
  420.     /**
  421.      * Updates the data to be signed or verified, using the specified
  422.      * array of bytes, starting at the specified offset.  
  423.      *
  424.      * @param data the array of bytes.  
  425.      * @param off the offset to start from in the array of bytes.  
  426.      * @param len the number of bytes to use, starting at offset.
  427.      *  
  428.      * @exception SignatureException if this signature object is not 
  429.      * initialized properly.          
  430.      */
  431.     public final void update(byte[] data, int off, int len) 
  432.     throws SignatureException {
  433.         if (state == SIGN || state == VERIFY) {
  434.         engineUpdate(data, off, len);
  435.         } else {
  436.         throw new SignatureException("object not initialized for "
  437.                          + "signature or verification");
  438.         }
  439.     }
  440.  
  441.     /** 
  442.      * Returns the name of the algorithm for this signature object.
  443.      * 
  444.      * @return the name of the algorithm for this signature object.
  445.      */
  446.     public final String getAlgorithm() {
  447.     return this.algorithm;
  448.     }
  449.  
  450.     /**
  451.      * Returns a string representation of this signature object,       
  452.      * providing information that includes the state of the object       
  453.      * and the name of the algorithm used.       
  454.      * 
  455.      * @return a string representation of this signature object.
  456.      */
  457.     public String toString() {
  458.     String initState = "";
  459.     switch (state) {
  460.     case UNINITIALIZED:
  461.         initState = "<not initialized>";
  462.         break;
  463.       case VERIFY:
  464.         initState = "<initialized for verifying>";
  465.         break;          
  466.       case SIGN:
  467.         initState = "<initialized for signing>";
  468.         break;          
  469.     }
  470.     return "Signature object: " + getAlgorithm() + initState;
  471.     }
  472.  
  473.     /**
  474.      * Sets the specified algorithm parameter to the specified value.
  475.      * This method supplies a general-purpose mechanism through
  476.      * which it is possible to set the various parameters of this object. 
  477.      * A parameter may be any settable parameter for the algorithm, such as 
  478.      * a parameter size, or a source of random bits for signature generation 
  479.      * (if appropriate), or an indication of whether or not to perform
  480.      * a specific but optional computation. A uniform algorithm-specific 
  481.      * naming scheme for each parameter is desirable but left unspecified 
  482.      * at this time.
  483.      *
  484.      * @param param the string identifier of the parameter.
  485.      * @param value the parameter value.
  486.      *
  487.      * @exception InvalidParameterException if <code>param</code> is an
  488.      * invalid parameter for this signature algorithm engine,
  489.      * the parameter is already set
  490.      * and cannot be set again, a security exception occurs, and so on.
  491.      *
  492.      * @deprecated Use <a href = 
  493.      * "#setParameter(java.security.spec.AlgorithmParameterSpec)">
  494.      * setParameter</a>.
  495.      */
  496.     public final void setParameter(String param, Object value) 
  497.     throws InvalidParameterException {
  498.         engineSetParameter(param, value);
  499.     }
  500.  
  501.     /**
  502.      * Initializes this signature engine with the specified parameter set.
  503.      *
  504.      * @param params the parameters
  505.      *
  506.      * @exception InvalidAlgorithmParameterException if the given parameters
  507.      * are inappropriate for this signature engine
  508.      */
  509.     public final void setParameter(AlgorithmParameterSpec params)
  510.     throws InvalidAlgorithmParameterException {
  511.         engineSetParameter(params);
  512.     }
  513.  
  514.     /**
  515.      * Gets the value of the specified algorithm parameter. This method 
  516.      * supplies a general-purpose mechanism through which it is possible to 
  517.      * get the various parameters of this object. A parameter may be any 
  518.      * settable parameter for the algorithm, such as a parameter size, or 
  519.      * a source of random bits for signature generation (if appropriate), 
  520.      * or an indication of whether or not to perform a specific but optional 
  521.      * computation. A uniform algorithm-specific naming scheme for each 
  522.      * parameter is desirable but left unspecified at this time.
  523.      *
  524.      * @param param the string name of the parameter.
  525.      *
  526.      * @return the object that represents the parameter value, or null if
  527.      * there is none.
  528.      *
  529.      * @exception InvalidParameterException if <code>param</code> is an invalid
  530.      * parameter for this engine, or another exception occurs while
  531.      * trying to get this parameter.
  532.      *
  533.      * @deprecated
  534.      */
  535.     public final Object getParameter(String param) 
  536.     throws InvalidParameterException {
  537.         return engineGetParameter(param);
  538.     }
  539.  
  540.     /**
  541.      * Returns a clone if the implementation is cloneable.
  542.      * 
  543.      * @return a clone if the implementation is cloneable.
  544.      *
  545.      * @exception CloneNotSupportedException if this is called
  546.      * on an implementation that does not support <code>Cloneable</code>.
  547.      */
  548.     public Object clone() throws CloneNotSupportedException {
  549.     if (this instanceof Cloneable) {
  550.         return super.clone();
  551.     } else {
  552.         throw new CloneNotSupportedException();
  553.     }
  554.     }
  555.  
  556.     // private debugging method.
  557.     private static void debug(String statement) {
  558.     if (debug) {
  559.         System.err.println(statement);
  560.     }
  561.     }
  562.  
  563.     // private debugging method.
  564.     private static void debug(Exception e) {
  565.     if (debug) {
  566.         e.printStackTrace();
  567.     }
  568.     }
  569.  
  570.  
  571.  
  572.  
  573.     /*
  574.      * The following class allows providers to extend from SignatureSpi
  575.      * rather than from Signature. It represents a Signature with an
  576.      * encapsulated, provider-supplied SPI object (of type SignatureSpi).
  577.      * If the provider implementation is an instance of SignatureSpi, the
  578.      * getInstance() methods above return an instance of this class, with
  579.      * the SPI object encapsulated.
  580.      *
  581.      * Note: All SPI methods from the original Signature class have been
  582.      * moved up the hierarchy into a new class (SignatureSpi), which has
  583.      * been interposed in the hierarchy between the API (Signature)
  584.      * and its original parent (Object).
  585.      */
  586.  
  587.     static class Delegate extends Signature {
  588.  
  589.     // The provider implementation (delegate)
  590.     private SignatureSpi sigSpi;
  591.  
  592.     // constructor
  593.     public Delegate(SignatureSpi sigSpi, String algorithm) {
  594.         super(algorithm);
  595.         this.sigSpi = sigSpi;
  596.     }
  597.  
  598.     /*
  599.      * Returns a clone if the delegate is cloneable.    
  600.      * 
  601.      * @return a clone if the delegate is cloneable.
  602.      *
  603.      * @exception CloneNotSupportedException if this is called on a
  604.      * delegate that does not support <code>Cloneable</code>.
  605.      */
  606.     public Object clone() throws CloneNotSupportedException {
  607.         if (sigSpi instanceof Cloneable) {
  608.         SignatureSpi sigSpiClone = (SignatureSpi)sigSpi.clone();
  609.         // Because 'algorithm' and 'provider' are private
  610.         // members of our supertype, we must perform a cast to
  611.         // access them.
  612.         Signature that =
  613.             new Delegate(sigSpiClone, ((Signature)this).algorithm);
  614.         that.provider = ((Signature)this).provider;
  615.         return that;
  616.         } else {
  617.         throw new CloneNotSupportedException();
  618.         }
  619.     }
  620.  
  621.     protected void engineInitVerify(PublicKey publicKey)
  622.         throws InvalidKeyException {
  623.         sigSpi.engineInitVerify(publicKey);
  624.     }
  625.  
  626.     protected void engineInitSign(PrivateKey privateKey)
  627.         throws InvalidKeyException {
  628.         sigSpi.engineInitSign(privateKey);
  629.     }
  630.  
  631.     protected void engineUpdate(byte b) throws SignatureException {
  632.         sigSpi.engineUpdate(b);
  633.     }
  634.  
  635.     protected void engineUpdate(byte[] b, int off, int len) 
  636.         throws SignatureException {
  637.         sigSpi.engineUpdate(b, off, len);
  638.     }
  639.     
  640.     protected byte[] engineSign() throws SignatureException {
  641.         return sigSpi.engineSign();
  642.     }
  643.  
  644.     protected int engineSign(byte[] outbuf, int offset, int len)
  645.         throws SignatureException {
  646.         return sigSpi.engineSign(outbuf, offset, len);
  647.     }
  648.  
  649.     protected boolean engineVerify(byte[] sigBytes) 
  650.         throws SignatureException {
  651.         return sigSpi.engineVerify(sigBytes);
  652.     }
  653.  
  654.     protected void engineSetParameter(String param, Object value) 
  655.         throws InvalidParameterException {
  656.         sigSpi.engineSetParameter(param, value);
  657.     }
  658.  
  659.     protected void engineSetParameter(AlgorithmParameterSpec params)
  660.         throws InvalidAlgorithmParameterException {
  661.         sigSpi.engineSetParameter(params);
  662.     }
  663.  
  664.     protected Object engineGetParameter(String param)
  665.         throws InvalidParameterException {
  666.         return sigSpi.engineGetParameter(param);
  667.     }
  668.     }
  669. }
  670.     
  671.         
  672.  
  673.  
  674.  
  675.         
  676.         
  677.     
  678.