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
27package java.security;
28
29import java.security.spec.AlgorithmParameterSpec;
30import java.util.*;
31import java.io.*;
32
33import java.nio.ByteBuffer;
34
35import sun.security.jca.JCAUtil;
36
37/**
38 * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
39 * for the <code>Signature</code> 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
53public 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     */
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     */
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     */
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     */
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     */
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()</code> bytes
135     * starting at at <code>data.position()</code>.
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     */
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     */
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</code>, starting at
188     * <code>offset</code>.
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</code> 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</code> where the signature is
205     * stored.
206     *
207     * @param len number of bytes within <code>outbuf</code> 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</code>
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</code> is less
221     * than the actual signature length.
222     *
223     * @since 1.2
224     */
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     */
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     */
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</code> 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
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     */
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     */
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</code> 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."
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</code>.
384     */
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