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