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