45 * |
46 * |
46 * <pre>{@code |
47 * <pre>{@code |
47 * Signature signingEngine = Signature.getInstance(algorithm, |
48 * Signature signingEngine = Signature.getInstance(algorithm, |
48 * provider); |
49 * provider); |
49 * SignedObject so = new SignedObject(myobject, signingKey, |
50 * SignedObject so = new SignedObject(myobject, signingKey, |
50 * signingEngine); |
51 * signingParams, signingEngine); |
51 * }</pre> |
52 * }</pre> |
52 * |
53 * |
53 * <p> A typical usage for verification is the following (having |
54 * <p> A typical usage for verification is the following (having |
54 * received SignedObject {@code so}): |
55 * received SignedObject {@code so}): |
55 * |
56 * |
56 * <pre>{@code |
57 * <pre>{@code |
57 * Signature verificationEngine = |
58 * Signature verificationEngine = |
58 * Signature.getInstance(algorithm, provider); |
59 * Signature.getInstance(algorithm, provider); |
59 * if (so.verify(publickey, verificationEngine)) |
60 * if (so.verify(verificationKey, verificationParams, verificationEngine)) |
60 * try { |
61 * try { |
61 * Object myobj = so.getObject(); |
62 * Object myobj = so.getObject(); |
62 * } catch (java.lang.ClassNotFoundException e) {}; |
63 * } catch (java.lang.ClassNotFoundException e) {}; |
63 * }</pre> |
64 * }</pre> |
64 * |
65 * |
65 * <p> Several points are worth noting. First, there is no need to |
66 * <p> Several points are worth noting. First, there is no need to |
66 * initialize the signing or verification engine, as it will be |
67 * initialize the signing or verification engine, as it will be |
67 * re-initialized inside the constructor and the {@code verify} |
68 * re-initialized inside the constructor and the {@code verify} |
68 * method. Secondly, for verification to succeed, the specified |
69 * method. Secondly, for verification to succeed, the specified |
69 * public key must be the public key corresponding to the private key |
70 * public key must be the public key corresponding to the private key |
70 * used to generate the SignedObject. |
71 * used to generate the SignedObject. If signing parameters are used, |
|
72 * the same parameters must be specified when calling {@code verify} |
|
73 * method for verification to succeed. |
71 * |
74 * |
72 * <p> More importantly, for flexibility reasons, the |
75 * <p> More importantly, for flexibility reasons, the |
73 * constructor and {@code verify} method allow for |
76 * constructor and {@code verify} method allow for |
74 * customized signature engines, which can implement signature |
77 * customized signature engines, which can implement signature |
75 * algorithms that are not installed formally as part of a crypto |
78 * algorithms that are not installed formally as part of a crypto |
144 * @exception SignatureException if signing fails. |
147 * @exception SignatureException if signing fails. |
145 */ |
148 */ |
146 public SignedObject(Serializable object, PrivateKey signingKey, |
149 public SignedObject(Serializable object, PrivateKey signingKey, |
147 Signature signingEngine) |
150 Signature signingEngine) |
148 throws IOException, InvalidKeyException, SignatureException { |
151 throws IOException, InvalidKeyException, SignatureException { |
149 // creating a stream pipe-line, from a to b |
152 // creating a stream pipe-line, from a to b |
150 ByteArrayOutputStream b = new ByteArrayOutputStream(); |
153 ByteArrayOutputStream b = new ByteArrayOutputStream(); |
151 ObjectOutput a = new ObjectOutputStream(b); |
154 ObjectOutput a = new ObjectOutputStream(b); |
152 |
155 |
153 // write and flush the object content to byte array |
156 // write and flush the object content to byte array |
154 a.writeObject(object); |
157 a.writeObject(object); |
155 a.flush(); |
158 a.flush(); |
156 a.close(); |
159 a.close(); |
157 this.content = b.toByteArray(); |
160 this.content = b.toByteArray(); |
158 b.close(); |
161 b.close(); |
159 |
162 |
160 // now sign the encapsulated object |
163 // now sign the encapsulated object |
161 this.sign(signingKey, signingEngine); |
164 try { |
|
165 this.sign(signingKey, null, signingEngine); |
|
166 } catch (InvalidAlgorithmParameterException e) { |
|
167 // should not happen, re-throw just in case |
|
168 throw new SignatureException(e); |
|
169 } |
|
170 } |
|
171 |
|
172 /** |
|
173 * Constructs a SignedObject from any Serializable object. |
|
174 * The given object is signed with the given signing key and |
|
175 * signature parameters, using the designated signature engine. |
|
176 * If the signature algorithm does not use any signature parameters, |
|
177 * {@code signingParams} should be null. |
|
178 * |
|
179 * @param object the object to be signed. |
|
180 * @param signingKey the private key for signing. |
|
181 * @param signingParams the signature parameters used for signing, |
|
182 * may be null. |
|
183 * @param signingEngine the signature signing engine. |
|
184 * |
|
185 * @exception IOException if an error occurs during serialization |
|
186 * @exception InvalidKeyException if the key is invalid. |
|
187 * @exception InvalidAlgorithmParameterException if the given signature |
|
188 * parameters is invalid. |
|
189 * @exception SignatureException if signing fails. |
|
190 * @since 11 |
|
191 */ |
|
192 public SignedObject(Serializable object, PrivateKey signingKey, |
|
193 AlgorithmParameterSpec signingParams, |
|
194 Signature signingEngine) |
|
195 throws IOException, InvalidKeyException, |
|
196 InvalidAlgorithmParameterException, SignatureException { |
|
197 // creating a stream pipe-line, from a to b |
|
198 ByteArrayOutputStream b = new ByteArrayOutputStream(); |
|
199 ObjectOutput a = new ObjectOutputStream(b); |
|
200 |
|
201 // write and flush the object content to byte array |
|
202 a.writeObject(object); |
|
203 a.flush(); |
|
204 a.close(); |
|
205 this.content = b.toByteArray(); |
|
206 b.close(); |
|
207 |
|
208 // now sign the encapsulated object |
|
209 this.sign(signingKey, signingParams, signingEngine); |
162 } |
210 } |
163 |
211 |
164 /** |
212 /** |
165 * Retrieves the encapsulated object. |
213 * Retrieves the encapsulated object. |
166 * The encapsulated object is de-serialized before it is returned. |
214 * The encapsulated object is de-serialized before it is returned. |
220 * is valid, {@code false} otherwise |
268 * is valid, {@code false} otherwise |
221 */ |
269 */ |
222 public boolean verify(PublicKey verificationKey, |
270 public boolean verify(PublicKey verificationKey, |
223 Signature verificationEngine) |
271 Signature verificationEngine) |
224 throws InvalidKeyException, SignatureException { |
272 throws InvalidKeyException, SignatureException { |
225 verificationEngine.initVerify(verificationKey); |
273 try { |
226 verificationEngine.update(this.content.clone()); |
274 return verify(verificationKey, null, verificationEngine); |
227 return verificationEngine.verify(this.signature.clone()); |
275 } catch (InvalidAlgorithmParameterException e) { |
|
276 // should not happen, re-throw just in case |
|
277 throw new SignatureException(e); |
|
278 } |
|
279 } |
|
280 |
|
281 /** |
|
282 * Verifies that the signature in this SignedObject is the valid |
|
283 * signature for the object stored inside, with the given |
|
284 * verification key and signature parameters, using the designated |
|
285 * verification engine. If the signature algorithm does not use any |
|
286 * signature parameters, {@code verificationParams} should be null. |
|
287 * When signature parameters are used in signing, the same parameters |
|
288 * must be specified when calling {@code verify} method for the |
|
289 * verification to succeed. |
|
290 * |
|
291 * @param verificationKey the public key for verification. |
|
292 * @param verificationParams the signature parameters for verification. |
|
293 * @param verificationEngine the signature verification engine. |
|
294 * |
|
295 * @exception SignatureException if signature verification failed (an |
|
296 * exception prevented the signature verification engine from completing |
|
297 * normally). |
|
298 * @exception InvalidKeyException if the verification key is invalid. |
|
299 * @exception InvalidAlgorithmParameterException if the given signature |
|
300 * parameters is invalid |
|
301 * @return {@code true} if the signature is valid, {@code false} otherwise |
|
302 * @since 11 |
|
303 */ |
|
304 public boolean verify(PublicKey verificationKey, |
|
305 AlgorithmParameterSpec verificationParams, |
|
306 Signature verificationEngine) |
|
307 throws InvalidKeyException, InvalidAlgorithmParameterException, |
|
308 SignatureException { |
|
309 // set parameteres before Signature.initSign/initVerify call, |
|
310 // so key can be checked when it's set |
|
311 try { |
|
312 verificationEngine.setParameter(verificationParams); |
|
313 } catch (UnsupportedOperationException e) { |
|
314 // for backward compatibility, only re-throw when |
|
315 // parameters is not null |
|
316 if (verificationParams != null) throw e; |
|
317 } |
|
318 verificationEngine.initVerify(verificationKey); |
|
319 verificationEngine.update(this.content.clone()); |
|
320 return verificationEngine.verify(this.signature.clone()); |
228 } |
321 } |
229 |
322 |
230 /* |
323 /* |
231 * Signs the encapsulated object with the given signing key, using the |
324 * Signs the encapsulated object with the given signing key, using the |
232 * designated signature engine. |
325 * designated signature engine. |
233 * |
326 * |
234 * @param signingKey the private key for signing. |
327 * @param signingKey the private key for signing. |
|
328 * @param signingParams the signature parameters for signing. |
235 * @param signingEngine the signature signing engine. |
329 * @param signingEngine the signature signing engine. |
236 * |
330 * |
237 * @exception InvalidKeyException if the key is invalid. |
331 * @exception InvalidKeyException if the key is invalid. |
|
332 * @exception InvalidAlgorithmParameterException if the given signature |
|
333 * parameters is invalid |
238 * @exception SignatureException if signing fails. |
334 * @exception SignatureException if signing fails. |
239 */ |
335 */ |
240 private void sign(PrivateKey signingKey, Signature signingEngine) |
336 private void sign(PrivateKey signingKey, |
241 throws InvalidKeyException, SignatureException { |
337 AlgorithmParameterSpec signingParams, |
242 // initialize the signing engine |
338 Signature signingEngine) |
243 signingEngine.initSign(signingKey); |
339 throws InvalidKeyException, InvalidAlgorithmParameterException, |
244 signingEngine.update(this.content.clone()); |
340 SignatureException { |
245 this.signature = signingEngine.sign().clone(); |
341 // set parameteres before Signature.initSign/initVerify call, |
246 this.thealgorithm = signingEngine.getAlgorithm(); |
342 // so key can be checked when it's set |
|
343 try { |
|
344 signingEngine.setParameter(signingParams); |
|
345 } catch (UnsupportedOperationException e) { |
|
346 // for backward compatibility, only re-throw when |
|
347 // parameters is not null |
|
348 if (signingParams != null) throw e; |
|
349 } |
|
350 signingEngine.initSign(signingKey); |
|
351 signingEngine.update(this.content.clone()); |
|
352 this.signature = signingEngine.sign().clone(); |
|
353 this.thealgorithm = signingEngine.getAlgorithm(); |
247 } |
354 } |
248 |
355 |
249 /** |
356 /** |
250 * readObject is called to restore the state of the SignedObject from |
357 * readObject is called to restore the state of the SignedObject from |
251 * a stream. |
358 * a stream. |
252 */ |
359 */ |
253 private void readObject(java.io.ObjectInputStream s) |
360 private void readObject(java.io.ObjectInputStream s) |
254 throws java.io.IOException, ClassNotFoundException { |
361 throws java.io.IOException, ClassNotFoundException { |
255 java.io.ObjectInputStream.GetField fields = s.readFields(); |
362 java.io.ObjectInputStream.GetField fields = s.readFields(); |
256 content = ((byte[])fields.get("content", null)).clone(); |
363 content = ((byte[])fields.get("content", null)).clone(); |
257 signature = ((byte[])fields.get("signature", null)).clone(); |
364 signature = ((byte[])fields.get("signature", null)).clone(); |
258 thealgorithm = (String)fields.get("thealgorithm", null); |
365 thealgorithm = (String)fields.get("thealgorithm", null); |
259 } |
366 } |
260 } |
367 } |