1 /*
2  * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package java.security;
27 
28 import java.security.spec.AlgorithmParameterSpec;
29 import java.util.*;
30 import java.io.*;
31 
32 import java.nio.ByteBuffer;
33 
34 import sun.security.jca.JCAUtil;
35 
36 /**
37  * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
38  * for the {@code Signature} class, which is used to provide the
39  * functionality of a digital signature algorithm. Digital signatures are used
40  * for authentication and integrity assurance of digital data.
41  *
42  * <p> All the abstract methods in this class must be implemented by each
43  * cryptographic service provider who wishes to supply the implementation
44  * of a particular signature algorithm.
45  *
46  * @author Benjamin Renaud
47  * @since 1.2
48  *
49  *
50  * @see Signature
51  */
52 
53 public abstract class SignatureSpi {
54 
55     /**
56      * Constructor for subclasses to call.
57      */
SignatureSpi()58     public SignatureSpi() {}
59 
60     /**
61      * Application-specified source of randomness.
62      */
63     protected SecureRandom appRandom = null;
64 
65     /**
66      * Initializes this signature object with the specified
67      * public key for verification operations.
68      *
69      * @param publicKey the public key of the identity whose signature is
70      * going to be verified.
71      *
72      * @throws    InvalidKeyException if the key is improperly
73      * encoded, parameters are missing, and so on.
74      */
engineInitVerify(PublicKey publicKey)75     protected abstract void engineInitVerify(PublicKey publicKey)
76         throws InvalidKeyException;
77 
78     /**
79      * Initializes this signature object with the specified
80      * public key for verification operations.
81      *
82      * @param publicKey the public key of the identity whose signature is
83      * going to be verified.
84      * @param params the parameters for generating this signature
85      *
86      * @throws    InvalidKeyException if the key is improperly
87      * encoded, does not work with the given parameters, and so on.
88      * @throws    InvalidAlgorithmParameterException if the given parameters
89      * is invalid.
90      */
engineInitVerify(PublicKey publicKey, AlgorithmParameterSpec params)91     void engineInitVerify(PublicKey publicKey,
92             AlgorithmParameterSpec params)
93             throws InvalidKeyException, InvalidAlgorithmParameterException {
94         if (params != null) {
95             try {
96                 engineSetParameter(params);
97             } catch (UnsupportedOperationException usoe) {
98                 // error out if not overridden
99                 throw new InvalidAlgorithmParameterException(usoe);
100             }
101         }
102         engineInitVerify(publicKey);
103     }
104 
105     /**
106      * Initializes this signature object with the specified
107      * private key for signing operations.
108      *
109      * @param privateKey the private key of the identity whose signature
110      * will be generated.
111      *
112      * @throws    InvalidKeyException if the key is improperly
113      * encoded, parameters are missing, and so on.
114      */
engineInitSign(PrivateKey privateKey)115     protected abstract void engineInitSign(PrivateKey privateKey)
116         throws InvalidKeyException;
117 
118     /**
119      * Initializes this signature object with the specified
120      * private key and source of randomness for signing operations.
121      *
122      * <p>This concrete method has been added to this previously-defined
123      * abstract class. (For backwards compatibility, it cannot be abstract.)
124      *
125      * @param privateKey the private key of the identity whose signature
126      * will be generated.
127      * @param random the source of randomness
128      *
129      * @throws    InvalidKeyException if the key is improperly
130      * encoded, parameters are missing, and so on.
131      */
engineInitSign(PrivateKey privateKey, SecureRandom random)132     protected void engineInitSign(PrivateKey privateKey,
133             SecureRandom random)
134             throws InvalidKeyException {
135         this.appRandom = random;
136         engineInitSign(privateKey);
137     }
138 
139     /**
140      * Initializes this signature object with the specified
141      * private key and source of randomness for signing operations.
142      *
143      * <p>This concrete method has been added to this previously-defined
144      * abstract class. (For backwards compatibility, it cannot be abstract.)
145      *
146      * @param privateKey the private key of the identity whose signature
147      * will be generated.
148      * @param params the parameters for generating this signature
149      * @param random the source of randomness
150      *
151      * @throws    InvalidKeyException if the key is improperly
152      * encoded, parameters are missing, and so on.
153      * @throws    InvalidAlgorithmParameterException if the parameters is
154      * invalid.
155      */
engineInitSign(PrivateKey privateKey, AlgorithmParameterSpec params, SecureRandom random)156     void engineInitSign(PrivateKey privateKey,
157             AlgorithmParameterSpec params, SecureRandom random)
158             throws InvalidKeyException, InvalidAlgorithmParameterException {
159         if (params != null) {
160             try {
161                 engineSetParameter(params);
162             } catch (UnsupportedOperationException usoe) {
163                 // error out if not overridden
164                 throw new InvalidAlgorithmParameterException(usoe);
165             }
166         }
167         engineInitSign(privateKey, random);
168     }
169 
170     /**
171      * Updates the data to be signed or verified
172      * using the specified byte.
173      *
174      * @param b the byte to use for the update.
175      *
176      * @throws    SignatureException if the engine is not initialized
177      * properly.
178      */
engineUpdate(byte b)179     protected abstract void engineUpdate(byte b) throws SignatureException;
180 
181     /**
182      * Updates the data to be signed or verified, using the
183      * specified array of bytes, starting at the specified offset.
184      *
185      * @param b the array of bytes
186      * @param off the offset to start from in the array of bytes
187      * @param len the number of bytes to use, starting at offset
188      *
189      * @throws    SignatureException if the engine is not initialized
190      * properly
191      */
engineUpdate(byte[] b, int off, int len)192     protected abstract void engineUpdate(byte[] b, int off, int len)
193             throws SignatureException;
194 
195     /**
196      * Updates the data to be signed or verified using the specified
197      * ByteBuffer. Processes the {@code data.remaining()} bytes
198      * starting at {@code data.position()}.
199      * Upon return, the buffer's position will be equal to its limit;
200      * its limit will not have changed.
201      *
202      * @param input the ByteBuffer
203      * @since 1.5
204      */
engineUpdate(ByteBuffer input)205     protected void engineUpdate(ByteBuffer input) {
206         if (input.hasRemaining() == false) {
207             return;
208         }
209         try {
210             if (input.hasArray()) {
211                 byte[] b = input.array();
212                 int ofs = input.arrayOffset();
213                 int pos = input.position();
214                 int lim = input.limit();
215                 engineUpdate(b, ofs + pos, lim - pos);
216                 input.position(lim);
217             } else {
218                 int len = input.remaining();
219                 byte[] b = new byte[JCAUtil.getTempArraySize(len)];
220                 while (len > 0) {
221                     int chunk = Math.min(len, b.length);
222                     input.get(b, 0, chunk);
223                     engineUpdate(b, 0, chunk);
224                     len -= chunk;
225                 }
226             }
227         } catch (SignatureException e) {
228             // is specified to only occur when the engine is not initialized
229             // this case should never occur as it is caught in Signature.java
230             throw new ProviderException("update() failed", e);
231         }
232     }
233 
234     /**
235      * Returns the signature bytes of all the data
236      * updated so far.
237      * The format of the signature depends on the underlying
238      * signature scheme.
239      *
240      * @return the signature bytes of the signing operation's result.
241      *
242      * @throws    SignatureException if the engine is not
243      * initialized properly or if this signature algorithm is unable to
244      * process the input data provided.
245      */
engineSign()246     protected abstract byte[] engineSign() throws SignatureException;
247 
248     /**
249      * Finishes this signature operation and stores the resulting signature
250      * bytes in the provided buffer {@code outbuf}, starting at
251      * {@code offset}.
252      * The format of the signature depends on the underlying
253      * signature scheme.
254      *
255      * <p>The signature implementation is reset to its initial state
256      * (the state it was in after a call to one of the
257      * {@code engineInitSign} methods)
258      * and can be reused to generate further signatures with the same private
259      * key.
260      *
261      * This method should be abstract, but we leave it concrete for
262      * binary compatibility.  Knowledgeable providers should override this
263      * method.
264      *
265      * @param outbuf buffer for the signature result.
266      *
267      * @param offset offset into {@code outbuf} where the signature is
268      * stored.
269      *
270      * @param len number of bytes within {@code outbuf} allotted for the
271      * signature.
272      * Both this default implementation and the SUN provider do not
273      * return partial digests. If the value of this parameter is less
274      * than the actual signature length, this method will throw a
275      * SignatureException.
276      * This parameter is ignored if its value is greater than or equal to
277      * the actual signature length.
278      *
279      * @return the number of bytes placed into {@code outbuf}
280      *
281      * @throws    SignatureException if the engine is not
282      * initialized properly, if this signature algorithm is unable to
283      * process the input data provided, or if {@code len} is less
284      * than the actual signature length.
285      *
286      * @since 1.2
287      */
engineSign(byte[] outbuf, int offset, int len)288     protected int engineSign(byte[] outbuf, int offset, int len)
289              throws SignatureException {
290         byte[] sig = engineSign();
291         if (len < sig.length) {
292                 throw new SignatureException
293                     ("partial signatures not returned");
294         }
295         if (outbuf.length - offset < sig.length) {
296                 throw new SignatureException
297                     ("insufficient space in the output buffer to store the "
298                      + "signature");
299         }
300         System.arraycopy(sig, 0, outbuf, offset, sig.length);
301         return sig.length;
302     }
303 
304     /**
305      * Verifies the passed-in signature.
306      *
307      * @param sigBytes the signature bytes to be verified.
308      *
309      * @return true if the signature was verified, false if not.
310      *
311      * @throws    SignatureException if the engine is not
312      * initialized properly, the passed-in signature is improperly
313      * encoded or of the wrong type, if this signature algorithm is unable to
314      * process the input data provided, etc.
315      */
engineVerify(byte[] sigBytes)316     protected abstract boolean engineVerify(byte[] sigBytes)
317             throws SignatureException;
318 
319     /**
320      * Verifies the passed-in signature in the specified array
321      * of bytes, starting at the specified offset.
322      *
323      * <p> Note: Subclasses should overwrite the default implementation.
324      *
325      *
326      * @param sigBytes the signature bytes to be verified.
327      * @param offset the offset to start from in the array of bytes.
328      * @param length the number of bytes to use, starting at offset.
329      *
330      * @return true if the signature was verified, false if not.
331      *
332      * @throws    SignatureException if the engine is not
333      * initialized properly, the passed-in signature is improperly
334      * encoded or of the wrong type, if this signature algorithm is unable to
335      * process the input data provided, etc.
336      * @since 1.4
337      */
engineVerify(byte[] sigBytes, int offset, int length)338     protected boolean engineVerify(byte[] sigBytes, int offset, int length)
339             throws SignatureException {
340         byte[] sigBytesCopy = new byte[length];
341         System.arraycopy(sigBytes, offset, sigBytesCopy, 0, length);
342         return engineVerify(sigBytesCopy);
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      * @throws    InvalidParameterException if {@code param} 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     @Deprecated
engineSetParameter(String param, Object value)370     protected abstract void engineSetParameter(String param, Object value)
371             throws InvalidParameterException;
372 
373     /**
374      * <p>This method is overridden by providers to initialize
375      * this signature engine with the specified parameter set.
376      *
377      * @param params the parameters
378      *
379      * @throws    UnsupportedOperationException if this method is not
380      * overridden by a provider
381      *
382      * @throws    InvalidAlgorithmParameterException if this method is
383      * overridden by a provider and the given parameters
384      * are inappropriate for this signature engine
385      */
engineSetParameter(AlgorithmParameterSpec params)386     protected void engineSetParameter(AlgorithmParameterSpec params)
387             throws InvalidAlgorithmParameterException {
388         throw new UnsupportedOperationException();
389     }
390 
391     /**
392      * <p>This method is overridden by providers to return the parameters
393      * used with this signature engine.
394      *
395      * <p> If this signature engine has been initialized with parameters
396      * (by calling {@link #engineSetParameter(AlgorithmParameterSpec)} or
397      * {@link #engineSetParameter(String, Object)}) and the underlying signature
398      * implementation supports returning the parameters as
399      * {@code AlgorithmParameters}, this method returns the same parameters.
400      * If the parameters were not set, this method may return a combination
401      * of default and randomly generated parameter values if the
402      * underlying signature implementation supports it and can successfully
403      * generate them. Otherwise, {@code null} is returned.
404      *
405      * @return the parameters used with this signature engine, or {@code null}
406      *
407      * @throws    UnsupportedOperationException if this method is
408      * not overridden by a provider
409      * @since 1.4
410      */
engineGetParameters()411     protected AlgorithmParameters engineGetParameters() {
412         throw new UnsupportedOperationException();
413     }
414 
415     /**
416      * Gets the value of the specified algorithm parameter.
417      * This method supplies a general-purpose mechanism through which it
418      * is possible to get the various parameters of this object. A parameter
419      * may be any settable parameter for the algorithm, such as a parameter
420      * size, or  a source of random bits for signature generation (if
421      * appropriate), or an indication of whether or not to perform a
422      * specific but optional computation. A uniform algorithm-specific
423      * naming scheme for each parameter is desirable but left unspecified
424      * at this time.
425      *
426      * @param param the string name of the parameter.
427      *
428      * @return the object that represents the parameter value, or {@code null} if
429      * there is none.
430      *
431      * @throws    InvalidParameterException if {@code param} is an
432      * invalid parameter for this engine, or another exception occurs while
433      * trying to get this parameter.
434      *
435      * @deprecated
436      */
437     @Deprecated
engineGetParameter(String param)438     protected abstract Object engineGetParameter(String param)
439         throws InvalidParameterException;
440 
441     /**
442      * Returns a clone if the implementation is cloneable.
443      *
444      * @return a clone if the implementation is cloneable.
445      *
446      * @throws    CloneNotSupportedException if this is called
447      * on an implementation that does not support {@code Cloneable}.
448      */
clone()449     public Object clone() throws CloneNotSupportedException {
450         if (this instanceof Cloneable) {
451             return super.clone();
452         } else {
453             throw new CloneNotSupportedException();
454         }
455     }
456 }
457