• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 
18 package java.security;
19 
20 import java.nio.ByteBuffer;
21 import java.security.spec.AlgorithmParameterSpec;
22 
23 /**
24  * {@code SignatureSpi} is the <i>Service Provider Interface</i> (<b>SPI</b>)
25  * definition for {@link Signature}.
26  *
27  * @see Signature
28  */
29 public abstract class SignatureSpi {
30 
31     /**
32      * Implementation specific source of randomness.
33      */
34     protected SecureRandom appRandom;
35 
36     /**
37      * Initializes this {@code SignatureSpi} instance for signature
38      * verification, using the public key of the identity whose signature is
39      * going to be verified.
40      *
41      * @param publicKey
42      *            the public key.
43      * @throws InvalidKeyException
44      *             if {@code publicKey} is not valid.
45      */
engineInitVerify(PublicKey publicKey)46     protected abstract void engineInitVerify(PublicKey publicKey)
47             throws InvalidKeyException;
48 
49     /**
50      * Initializes this {@code SignatureSpi} instance for signing, using the
51      * private key of the identity whose signature is going to be generated.
52      *
53      * @param privateKey
54      *            the private key.
55      * @throws InvalidKeyException
56      *             if {@code privateKey} is not valid.
57      */
engineInitSign(PrivateKey privateKey)58     protected abstract void engineInitSign(PrivateKey privateKey)
59             throws InvalidKeyException;
60 
61     /**
62      * Initializes this {@code SignatureSpi} instance for signing, using the
63      * private key of the identity whose signature is going to be generated and
64      * the specified source of randomness.
65      *
66      * @param privateKey
67      *            the private key.
68      * @param random
69      *            the {@code SecureRandom} to use.
70      * @throws InvalidKeyException
71      *             if {@code privateKey} is not valid.
72      */
engineInitSign(PrivateKey privateKey, SecureRandom random)73     protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
74             throws InvalidKeyException {
75         appRandom = random;
76         engineInitSign(privateKey);
77     }
78 
79     /**
80      * Updates the data to be verified or to be signed, using the specified
81      * {@code byte}.
82      *
83      * @param b
84      *            the byte to update with.
85      * @throws SignatureException
86      *             if this {@code SignatureSpi} instance is not initialized
87      *             properly.
88      */
engineUpdate(byte b)89     protected abstract void engineUpdate(byte b) throws SignatureException;
90 
91     /**
92      * Updates the data to be verified or to be signed, using the given {@code
93      * byte[]}, starting form the specified index for the specified length.
94      *
95      * @param b
96      *            the byte array to update with.
97      * @param off
98      *            the start index in {@code b} of the data.
99      * @param len
100      *            the number of bytes to use.
101      * @throws SignatureException
102      *             if this {@code SignatureSpi} instance is not initialized
103      *             properly.
104      */
engineUpdate(byte[] b, int off, int len)105     protected abstract void engineUpdate(byte[] b, int off, int len)
106             throws SignatureException;
107 
108     /**
109      * Updates the data to be verified or to be signed, using the specified
110      * {@code ByteBuffer}.
111      *
112      * @param input
113      *            the {@code ByteBuffer} to update with.
114      * @throws RuntimeException
115      *             since {@code SignatureException} is not specified for this
116      *             method it throws a {@code RuntimeException} if underlying
117      *             {@link #engineUpdate(byte[], int, int)} throws {@code
118      *             SignatureException}.
119      */
engineUpdate(ByteBuffer input)120     protected void engineUpdate(ByteBuffer input) {
121         if (!input.hasRemaining()) {
122             return;
123         }
124         byte[] tmp;
125         if (input.hasArray()) {
126             tmp = input.array();
127             int offset = input.arrayOffset();
128             int position = input.position();
129             int limit = input.limit();
130             try {
131                 engineUpdate(tmp, offset + position, limit - position);
132             } catch (SignatureException e) {
133                 throw new RuntimeException(e); //Wrap SignatureException
134             }
135             input.position(limit);
136         } else {
137             tmp = new byte[input.limit() - input.position()];
138             input.get(tmp);
139             try {
140                 engineUpdate(tmp, 0, tmp.length);
141             } catch (SignatureException e) {
142                 throw new RuntimeException(e); //Wrap SignatureException
143             }
144         }
145     }
146 
147     /**
148      * Generates and returns the signature of all updated data.
149      * <p>
150      * This {@code SignatureSpi} instance is reset to the state of its last
151      * initialization for signing and thus can be used for another signature
152      * from the same identity.
153      *
154      * @return the signature of all updated data.
155      * @throws SignatureException
156      *             if this {@code SignatureSpi} instance is not initialized
157      *             properly.
158      */
engineSign()159     protected abstract byte[] engineSign() throws SignatureException;
160 
161     /**
162      * Generates and stores the signature of all updated data in the provided
163      * {@code byte[]} at the specified position with the specified length.
164      * <p>
165      * This {@code SignatureSpi} instance is reset to the state of its last
166      * initialization for signing and thus can be used for another signature
167      * from the same identity.
168      *
169      * @param outbuf
170      *            the buffer to store the signature.
171      * @param offset
172      *            the index of the first byte in {@code outbuf} to store.
173      * @param len
174      *            the number of bytes allocated for the signature.
175      * @return the number of bytes stored in {@code outbuf}.
176      * @throws SignatureException
177      *             if this {@code SignatureSpi} instance is not initialized
178      *             properly.
179      * @throws IllegalArgumentException
180      *             if {@code offset} or {@code len} are not valid in respect to
181      *             {@code outbuf}.
182      */
engineSign(byte[] outbuf, int offset, int len)183     protected int engineSign(byte[] outbuf, int offset, int len) throws SignatureException {
184         byte[] tmp = engineSign();
185         if (tmp == null) {
186             return 0;
187         }
188         if (len < tmp.length) {
189             throw new SignatureException("The value of len parameter is less than the actual signature length");
190         }
191         if (offset < 0) {
192             throw new SignatureException("offset < 0");
193         }
194         if (offset + len > outbuf.length) {
195             throw new SignatureException("offset + len > outbuf.length");
196         }
197         System.arraycopy(tmp, 0, outbuf, offset, tmp.length);
198         return tmp.length;
199     }
200 
201     /**
202      * Indicates whether the given {@code sigBytes} can be verified using the
203      * public key or a certificate of the signer.
204      * <p>
205      * This {@code SignatureSpi} instance is reset to the state of its last
206      * initialization for verifying and thus can be used to verify another
207      * signature of the same signer.
208      *
209      * @param sigBytes
210      *            the signature to verify.
211      * @return {@code true} if the signature was verified, {@code false}
212      *         otherwise.
213      * @throws SignatureException
214      *             if this {@code SignatureSpi} instance is not initialized
215      *             properly.
216      */
engineVerify(byte[] sigBytes)217     protected abstract boolean engineVerify(byte[] sigBytes)
218             throws SignatureException;
219 
220     /**
221      * Indicates whether the given {@code sigBytes} starting at index {@code
222      * offset} with {@code length} bytes can be verified using the public key or
223      * a certificate of the signer.
224      * <p>
225      * This {@code SignatureSpi} instance is reset to the state of its last
226      * initialization for verifying and thus can be used to verify another
227      * signature of the same signer.
228      *
229      * @param sigBytes
230      *            the {@code byte[]} containing the signature to verify.
231      * @param offset
232      *            the start index in {@code sigBytes} of the signature
233      * @param length
234      *            the number of bytes allocated for the signature.
235      * @return {@code true} if the signature was verified, {@code false}
236      *         otherwise.
237      * @throws SignatureException
238      *             if this {@code SignatureSpi} instance is not initialized
239      *             properly.
240      * @throws IllegalArgumentException
241      *             if {@code offset} or {@code length} are not valid in respect
242      *             to {@code sigBytes}.
243      */
engineVerify(byte[] sigBytes, int offset, int length)244     protected boolean engineVerify(byte[] sigBytes, int offset, int length)
245             throws SignatureException {
246         byte[] tmp = new byte[length];
247         System.arraycopy(sigBytes, offset, tmp, 0, length);
248         return engineVerify(tmp);
249     }
250 
251     /**
252      * Sets the specified parameter to the given value.
253      *
254      * @param param
255      *            the name of the parameter.
256      * @param value
257      *            the parameter value.
258      * @throws InvalidParameterException
259      *             if the parameter is invalid, already set or is not allowed to
260      *             be changed.
261      * @deprecated Use {@link #engineSetParameter(AlgorithmParameterSpec)}
262      */
263     @Deprecated
engineSetParameter(String param, Object value)264     protected abstract void engineSetParameter(String param, Object value)
265             throws InvalidParameterException;
266 
267     /**
268      * Sets the specified {@code AlgorithmParameterSpec}.
269      *
270      * @param params
271      *            the parameter to set.
272      * @throws InvalidAlgorithmParameterException
273      *             if the parameter is invalid, already set or is not allowed to
274      *             be changed.
275      */
engineSetParameter(AlgorithmParameterSpec params)276     protected void engineSetParameter(AlgorithmParameterSpec params)
277             throws InvalidAlgorithmParameterException {
278         throw new UnsupportedOperationException();
279     }
280 
281     /**
282      * Returns the {@code AlgorithmParameters} of this {@link SignatureSpi}
283      * instance.
284      *
285      * @return the {@code AlgorithmParameters} of this {@link SignatureSpi}
286      *         instance, maybe {@code null}.
287      */
engineGetParameters()288     protected AlgorithmParameters engineGetParameters() {
289         throw new UnsupportedOperationException();
290     }
291 
292     /**
293      * Returns the value of the parameter with the specified name.
294      *
295      * @param param
296      *            the name of the requested parameter value.
297      * @return the value of the parameter with the specified name, maybe {@code
298      *         null}.
299      * @throws InvalidParameterException
300      *             if {@code param} is not a valid parameter for this {@code
301      *             SignatureSpi} or an other error occurs.
302      * @deprecated There is no generally accepted parameter naming convention.
303      */
304     @Deprecated
engineGetParameter(String param)305     protected abstract Object engineGetParameter(String param)
306             throws InvalidParameterException;
307 
308     @Override
clone()309     public Object clone() throws CloneNotSupportedException {
310         return super.clone();
311     }
312 }
313