1   /* $RCSfile: ISO9796Part1WithRSASignatureEngine.java,v $
2    * $Revision: 1.3 $
3    * $Date: 2003/10/04 19:18:38 $
4    * $Author: uwe_guenther $
5    * $State: Exp $
6    *
7    * Created on November 02, 2002 8:40 PM
8    *
9    * Copyright (C) 2002 Uwe Guenther <uwe@cscc.de>
10   *
11   * This file is part of the jhbci JCE-ServiceProvider. The jhbci JCE-
12   * ServiceProvider is a library, written in JavaTM, that should be 
13   * used in HBCI banking applications (clients and may be servers),
14   * to do cryptographic operations.
15   *
16   * The jhbci library is free software; you can redistribute it and/or
17   * modify it under the terms of the GNU Lesser General Public
18   * License as published by the Free Software Foundation; either
19   * version 2.1 of the License, or (at your option) any later version.
20   *
21   * The jhbci library is distributed in the hope that it will be useful,
22   * but WITHOUT ANY WARRANTY; without even the implied warranty of
23   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24   * Lesser General Public License for more details.
25   *
26   * You should have received a copy of the GNU Lesser General Public
27   * License along with this library; if not, write to the Free Software
28   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29   *
30   */
31  
32  package de.cscc.crypto.provider;
33  
34  import java.security.AlgorithmParameters;
35  import java.security.InvalidAlgorithmParameterException;
36  import java.security.InvalidKeyException;
37  import java.security.InvalidParameterException;
38  import java.security.PrivateKey;
39  import java.security.PublicKey;
40  import java.security.SecureRandom;
41  import java.security.SignatureException;
42  import java.security.SignatureSpi;
43  import java.security.spec.AlgorithmParameterSpec;
44  
45  /** 
46   * ISO9796Part1AndRSASignatureEngine Class.
47   *
48   * @author  <a href=mailto:uwe@cscc.de>Uwe G&uuml;nther</a>
49   *
50   * @version $Revision: 1.3 $
51   */
52  public final class ISO9796Part1WithRSASignatureEngine 
53  extends SignatureSpi implements Cloneable {
54  
55      private ISO9796Part1WithRSASignatureImpl sig = 
56      new ISO9796Part1WithRSASignatureImpl();
57      
58      /** Creates new ISO9796Part1WithRSASignatureEngine.  */
59      public ISO9796Part1WithRSASignatureEngine() {
60          if (JHBCI.selfIntegrityChecking() == false) {
61              throw new SecurityException("JHBCI-Provider is tampered.");
62          }        
63      }
64  
65      /**
66       * Creates and returns a copy of this object.  
67       *
68       * @return a clone of this instance.
69       * @throws CloneNotSupportedException  if the object's class does not
70       * support the <code>Cloneable</code> interface. Subclasses
71       * that override the <code>clone</code> method can also
72       * throw this exception to indicate that an instance cannot
73       * be cloned.
74       */
75      public Object clone() throws CloneNotSupportedException {
76          ISO9796Part1WithRSASignatureEngine result =
77          (ISO9796Part1WithRSASignatureEngine) super.clone();
78          result.sig = 
79          (ISO9796Part1WithRSASignatureImpl) this.sig.clone();
80          return result;
81      }
82      
83      /**
84       * Indicates whether some other object is "equal to" this one.
85       *
86       * @param   obj   the reference object with which to compare.
87       * @return  <code>true</code> if this object is the same as the obj
88       *         argument; <code>false</code> otherwise.
89       * @see     #hashCode()
90       * @see     java.util.Hashtable
91       */
92      public boolean equals(Object obj) {
93          //Only for performance.
94          if (this == obj) {
95              return true;
96          } 
97          
98          //If obj == null then instanceof returns false, see JLS 15.20.2
99          if (!(obj instanceof ISO9796Part1WithRSASignatureEngine)) {
100             return false;
101         }
102         
103         ISO9796Part1WithRSASignatureEngine other = 
104         (ISO9796Part1WithRSASignatureEngine)obj;
105         
106         return this.sig.equals(other.sig);
107     }
108     
109     /**
110      * Returns a hash code value for the object. 
111      *
112      * @return  a hash code value for this object.
113      * @see     java.lang.Object#equals(java.lang.Object)
114      * @see     java.util.Hashtable
115      */
116     public int hashCode() {
117         int result = 17;
118         result = 37*result + this.sig.hashCode();
119         return result;
120     }
121     
122     /**
123      * Returns a string representation of the object. 
124      *
125      * @return  a string representation of the object.
126      */
127     public String toString() {
128         return this.sig.toString();
129     }
130     
131     /**
132      * Initializes this signature object with the specified
133      * private key for signing operations.
134      *
135      * @param privateKey the private key of the identity whose signature
136      * will be generated.
137      *
138      * @throws InvalidKeyException if the key is improperly encoded, parameters
139      * are missing, and so on.
140      */
141     protected void engineInitSign(PrivateKey privateKey) 
142     throws InvalidKeyException {
143         this.sig.initSign(privateKey);
144     }
145     
146     /**
147      * Initializes this signature object with the specified
148      * private key and source of randomness for signing operations.
149      *
150      * <p>This concrete method has been added to this previously-defined
151      * abstract class. (For backwards compatibility, it cannot be abstract.)
152      *
153      * @param privateKey the private key of the identity whose signature
154      * will be generated.
155      * @param random the source of randomness
156      *
157      * @throws InvalidKeyException if the key is improperly encoded, parameters 
158      * are missing, and so on.
159      */
160     protected void engineInitSign(PrivateKey privateKey, SecureRandom random) 
161     throws InvalidKeyException {
162         this.sig.initSign(privateKey, random);
163     }
164     
165     /**
166      * Initializes this signature object with the specified
167      * public key for verification operations.
168      *
169      * @param publicKey the public key of the identity whose signature is
170      * going to be verified.
171      *
172      * @throws InvalidKeyException if the key is improperly
173      * encoded, parameters are missing, and so on.
174      */
175     protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
176         this.sig.initVerify(publicKey);
177     }
178     
179     /**
180      * Updates the data to be signed or verified
181      * using the specified byte.
182      *
183      * @param value the byte to use for the update.
184      *
185      * @throws SignatureException if the engine is not initialized
186      * properly.
187      */
188     protected void engineUpdate(byte value) throws SignatureException {
189         this.sig.update(value);
190     }
191     
192     /**
193      * Updates the data to be signed or verified, using the
194      * specified array of bytes, starting at the specified offset.
195      *
196      * @param values the array of bytes
197      * @param offset the offset to start from in the array of bytes
198      * @param len the number of bytes to use, starting at offset
199      *
200      * @throws SignatureException if the engine is not initialized
201      * properly
202      * @throws NullPointerException if outbuf is null.
203      * @throws IllegalArgumentException if offset or len is negative, or the 
204      * sum of offset and len is greater than length of the values array.
205      */
206     protected void engineUpdate(byte[] values, int offset, int len) 
207     throws SignatureException {
208         this.sig.update(values, offset, len);
209     }
210     
211     /**
212      * Returns the signature bytes of all the data
213      * updated so far.
214      * The format of the signature depends on the underlying
215      * signature scheme.
216      *
217      * @return the signature bytes of the signing operation's result.
218      *
219      * @throws SignatureException if the engine is not initialized properly.
220      */
221     protected byte[] engineSign() throws SignatureException {
222         return this.sig.sign();
223     }
224     
225     /**
226      * Finishes this signature operation and stores the resulting signature
227      * bytes in the provided buffer <code>outbuf</code>, starting at
228      * <code>offset</code>.
229      * The format of the signature depends on the underlying
230      * signature scheme.
231      *
232      * <p>The signature implementation is reset to its initial state
233      * (the state it was in after a call to one of the
234      * <code>engineInitSign</code> methods)
235      * and can be reused to generate further signatures with the same private
236      * key.
237      *
238      * This method should be abstract, but we leave it concrete for
239      * binary compatibility.  Knowledgeable providers should override this
240      * method.
241      *
242      * @param outbuf buffer for the signature result.
243      *
244      * @param offset offset into <code>outbuf</code> where the signature is
245      * stored.
246      *
247      * @param len number of bytes within <code>outbuf</code> allotted for the
248      * signature.
249      * Both this default implementation and the SUN provider do not
250      * return partial digests. If the value of this parameter is less
251      * than the actual signature length, this method will throw a
252      * SignatureException.
253      * This parameter is ignored if its value is greater than or equal to
254      * the actual signature length.
255      *
256      * @return the number of bytes placed into <code>outbuf</code>
257      *
258      * @throws SignatureException if an error occurs or <code>len</code>
259      * is less than the actual signature length.
260      * @throws NullPointerException if outbuf is null.
261      * @throws IllegalArgumentException if offset or len is negative, or the 
262      * sum of offset and len is greater than length of the outbuf array.
263      */
264     protected int engineSign(byte[] outbuf, int offset, int len) 
265     throws SignatureException {
266         return this.sig.sign(outbuf, offset, len);
267     }    
268     
269     /**
270      * Verifies the passed-in signature.
271      *
272      * @param sigBytes the signature bytes to be verified.
273      *
274      * @return true if the signature was verified, false if not.
275      *
276      * @throws SignatureException if the engine is not initialized
277      * properly, or the passed-in signature is improperly encoded or
278      * of the wrong type, etc.
279      */
280     protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
281         return this.sig.verify(sigBytes);
282     }
283     
284     /**
285      * Verifies the passed-in signature in the specified array
286      * of bytes, starting at the specified offset.
287      *
288      * <p> Note: Subclasses should overwrite the default implementation.
289      *
290      *
291      * @param sigBytes the signature bytes to be verified.
292      * @param offset the offset to start from in the array of bytes.
293      * @param len the number of bytes to use, starting at offset.
294      *
295      * @return true if the signature was verified, false if not.
296      *
297      * @throws SignatureException if the engine is not initialized
298      * properly, or the passed-in signature is improperly encoded or
299      * of the wrong type, etc.
300      */
301     protected boolean engineVerify(byte[] sigBytes, int offset, int len) 
302     throws SignatureException {
303         return this.sig.verify(sigBytes, offset, len);
304     }
305     
306     /**
307      * <p>This method is overridden by providers to initialize
308      * this signature engine with the specified parameter set.
309      *
310      * @param params the parameters
311      *
312      * @exception UnsupportedOperationException if this method is not
313      * overridden by a provider
314      *
315      * @throws InvalidAlgorithmParameterException if this method is
316      * overridden by a provider and the the given parameters
317      * are inappropriate for this signature engine
318      */
319     protected void engineSetParameter(AlgorithmParameterSpec params) 
320     throws InvalidAlgorithmParameterException {
321         this.sig.setParameter(params);
322     }
323     
324     /**
325      * <p>This method is overridden by providers to return the
326      * parameters used with this signature engine, or null
327      * if this signature engine does not use any parameters.
328      *
329      * <p>The returned parameters may be the same that were used to initialize
330      * this signature engine, or may contain a combination of default and
331      * randomly generated parameter values used by the underlying signature
332      * implementation if this signature engine requires algorithm parameters
333      * but was not initialized with any.
334      *
335      * @return the parameters used with this signature engine, or null if this
336      * signature engine does not use any parameters
337      *
338      * @throws UnsupportedOperationException if this method is
339      * not overridden by a provider
340      */
341     protected AlgorithmParameters engineGetParameters() {
342         return this.sig.getParameters();
343     }
344     
345     /**
346      * Sets the specified algorithm parameter to the specified
347      * value. This method supplies a general-purpose mechanism through
348      * which it is possible to set the various parameters of this object.
349      * A parameter may be any settable parameter for the algorithm, such as
350      * a parameter size, or a source of random bits for signature generation
351      * (if appropriate), or an indication of whether or not to perform
352      * a specific but optional computation. A uniform algorithm-specific
353      * naming scheme for each parameter is desirable but left unspecified
354      * at this time.
355      *
356      * @param param the string identifier of the parameter.
357      *
358      * @param value the parameter value.
359      *
360      * @exception InvalidParameterException if <code>param</code> is an
361      * invalid parameter for this signature algorithm engine,
362      * the parameter is already set
363      * and cannot be set again, a security exception occurs, and so on.
364      *
365      * @deprecated Replaced by {@link
366      * #engineSetParameter(java.security.spec.AlgorithmParameterSpec)
367      * engineSetParameter}.
368      */
369     protected void engineSetParameter(String param, Object value) 
370     throws InvalidParameterException {
371         throw new UnsupportedOperationException("Method deprecated.");
372     }
373     
374     /**
375      * Gets the value of the specified algorithm parameter.
376      * This method supplies a general-purpose mechanism through which it
377      * is possible to get the various parameters of this object. A parameter
378      * may be any settable parameter for the algorithm, such as a parameter
379      * size, or  a source of random bits for signature generation (if
380      * appropriate), or an indication of whether or not to perform a
381      * specific but optional computation. A uniform algorithm-specific
382      * naming scheme for each parameter is desirable but left unspecified
383      * at this time.
384      *
385      * @param param the string name of the parameter.
386      *
387      * @return the object that represents the parameter value, or null if
388      * there is none.
389      *
390      * @exception InvalidParameterException if <code>param</code> is an
391      * invalid parameter for this engine, or another exception occurs while
392      * trying to get this parameter.
393      *
394      * @deprecated
395      */
396     protected Object engineGetParameter(String param) 
397     throws InvalidParameterException {
398         throw new UnsupportedOperationException("Method deprecated.");
399     }
400     
401 }
402