java.security.Signature: NaN%
Overview
Search Parameters
- plot: false
- chromosome_length: 40
- static_hack: false
- tournament_size: 10
- max_int: 2048
- string_length: 20
- crossover_rate: 0.75
- max_attempts: 1000
- CP: src
- check_parents_length: true
- PREFIX: java.security
- stopping_condition: MaxStatements
- max_recursion: 10
- primitive_pool: 0.5
- selection_function: Rank
- generations: 1000000
- primitive_reuse_probability: 0.5
- test_excludes: test.excludes
- bloat_factor: 2
- object_reuse_probability: 0.9
- minimize: true
- html: true
- null_probability: 0.1
- strategy: EvoSuite
- elite: 1
- check_best_length: true
- num_tests: 2
- PROJECT_PREFIX: java.security
- OUTPUT_DIR: evosuite-files
- algorithm: SteadyStateGA
- string_replacement: true
- crossover_function: SinglePointRelative
- report_dir: evosuite-report
- test_includes: test.includes
- output_dir: evosuite-files
- criterion: branch
- rank_bias: 1.7
- timeout: 5000
- population: 100
- test_dir: evosuite-tests
- max_size: 100
- check_max_length: true
- TARGET_CLASS: java.security.Signature
- check_rank_length: true
- max_length: 5000
EvoSuite Parameters
- plot: false
- chromosome_length: 40
- static_hack: false
- tournament_size: 10
- max_int: 2048
- string_length: 20
- crossover_rate: 0.75
- max_attempts: 1000
- CP: src
- check_parents_length: true
- PREFIX: java.security
- stopping_condition: MaxStatements
- max_recursion: 10
- primitive_pool: 0.5
- selection_function: Rank
- generations: 1000000
- primitive_reuse_probability: 0.5
- test_excludes: test.excludes
- bloat_factor: 2
- object_reuse_probability: 0.9
- minimize: true
- html: true
- null_probability: 0.1
- strategy: EvoSuite
- elite: 1
- check_best_length: true
- num_tests: 2
- PROJECT_PREFIX: java.security
- OUTPUT_DIR: evosuite-files
- algorithm: SteadyStateGA
- string_replacement: true
- crossover_function: SinglePointRelative
- report_dir: evosuite-report
- test_includes: test.includes
- output_dir: evosuite-files
- criterion: branch
- rank_bias: 1.7
- timeout: 5000
- population: 100
- test_dir: evosuite-tests
- max_size: 100
- check_max_length: true
- TARGET_CLASS: java.security.Signature
- check_rank_length: true
- max_length: 5000
Old Parameters
- Algorithm: SteadyStateGA
- Population size: 100
- Initial test length: 40
- Stopping condition: MaxStatements: null
- Bloat control factor: 2
- Random seed: 0
Statistics
- Start time: 2010-10-18 20:24:48
- End time: 2010-10-18 20:25:04
- Fitness evaluations: 100
- Tests executed: 200
- Statements executed: 5105
- Generations: 2
- Number of tests before minimization: 2
- Number of tests after minimization: 0
- Length of tests before minimization: 12
- Length of tests after minimization: 0
- Total predicates: 0
- Total branches: 0
- Covered branches: 0
- Total methods: 0
- Covered methods: 0
- Methods without branches: 0
- Total coverage goal: 0
- Covered goals: 0
- Time for search: 0:00:15
- Time for minimization: 0:00:00
- Total time: 0:00:16
Test suite
Source Code
1: /*
2: * @(#)Signature.java 1.104 10/03/23
3: *
4: * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
5: * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6: */
7:
8: package java.security;
9:
10: import java.security.spec.AlgorithmParameterSpec;
11: import java.util.*;
12: import java.util.concurrent.ConcurrentHashMap;
13: import java.io.*;
14: import java.security.cert.Certificate;
15: import java.security.cert.X509Certificate;
16:
17: import java.nio.ByteBuffer;
18:
19: import java.security.Provider.Service;
20:
21: import javax.crypto.Cipher;
22: import javax.crypto.CipherSpi;
23: import javax.crypto.IllegalBlockSizeException;
24: import javax.crypto.BadPaddingException;
25: import javax.crypto.NoSuchPaddingException;
26:
27: import sun.security.util.Debug;
28: import sun.security.jca.*;
29: import sun.security.jca.GetInstance.Instance;
30:
31: /**
32: * This Signature class is used to provide applications the functionality
33: * of a digital signature algorithm. Digital signatures are used for
34: * authentication and integrity assurance of digital data.
35: *
36: * <p> The signature algorithm can be, among others, the NIST standard
37: * DSA, using DSA and SHA-1. The DSA algorithm using the
38: * SHA-1 message digest algorithm can be specified as <tt>SHA1withDSA</tt>.
39: * In the case of RSA, there are multiple choices for the message digest
40: * algorithm, so the signing algorithm could be specified as, for example,
41: * <tt>MD2withRSA</tt>, <tt>MD5withRSA</tt>, or <tt>SHA1withRSA</tt>.
42: * The algorithm name must be specified, as there is no default.
43: *
44: * <p> A Signature object can be used to generate and verify digital
45: * signatures.
46: *
47: * <p> There are three phases to the use of a Signature object for
48: * either signing data or verifying a signature:<ol>
49: *
50: * <li>Initialization, with either
51: *
52: * <ul>
53: *
54: * <li>a public key, which initializes the signature for
55: * verification (see {@link #initVerify(PublicKey) initVerify}), or
56: *
57: * <li>a private key (and optionally a Secure Random Number Generator),
58: * which initializes the signature for signing
59: * (see {@link #initSign(PrivateKey)}
60: * and {@link #initSign(PrivateKey, SecureRandom)}).
61: *
62: * </ul><p>
63: *
64: * <li>Updating<p>
65: *
66: * <p>Depending on the type of initialization, this will update the
67: * bytes to be signed or verified. See the
68: * {@link #update(byte) update} methods.<p>
69: *
70: * <li>Signing or Verifying a signature on all updated bytes. See the
71: * {@link #sign() sign} methods and the {@link #verify(byte[]) verify}
72: * method.
73: *
74: * </ol>
75: *
76: * <p>Note that this class is abstract and extends from
77: * <code>SignatureSpi</code> for historical reasons.
78: * Application developers should only take notice of the methods defined in
79: * this <code>Signature</code> class; all the methods in
80: * the superclass are intended for cryptographic service providers who wish to
81: * supply their own implementations of digital signature algorithms.
82: *
83: * @author Benjamin Renaud
84: *
85: * @version 1.104, 03/23/10
86: */
87:
88: public abstract class Signature extends SignatureSpi {
89:
90: private static final Debug debug =
91: Debug.getInstance("jca", "Signature");
92:
93: /*
94: * The algorithm for this signature object.
95: * This value is used to map an OID to the particular algorithm.
96: * The mapping is done in AlgorithmObject.algOID(String algorithm)
97: */
98: private String algorithm;
99:
100: // The provider
101: Provider provider;
102:
103: /**
104: * Possible {@link #state} value, signifying that
105: * this signature object has not yet been initialized.
106: */
107: protected final static int UNINITIALIZED = 0;
108:
109: /**
110: * Possible {@link #state} value, signifying that
111: * this signature object has been initialized for signing.
112: */
113: protected final static int SIGN = 2;
114:
115: /**
116: * Possible {@link #state} value, signifying that
117: * this signature object has been initialized for verification.
118: */
119: protected final static int VERIFY = 3;
120:
121: /**
122: * Current state of this signature object.
123: */
124: protected int state = UNINITIALIZED;
125:
126: /**
127: * Creates a Signature object for the specified algorithm.
128: *
129: * @param algorithm the standard string name of the algorithm.
130: * See Appendix A in the <a href=
131: * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
132: * Java Cryptography Architecture API Specification & Reference </a>
133: * for information about standard algorithm names.
134: */
135: protected Signature(String algorithm) {
136: this.algorithm = algorithm;
137: }
138:
139: // name of the special signature alg
140: private final static String RSA_SIGNATURE = "NONEwithRSA";
141:
142: // name of the equivalent cipher alg
143: private final static String RSA_CIPHER = "RSA/ECB/PKCS1Padding";
144:
145: // all the services we need to lookup for compatibility with Cipher
146: private final static List<ServiceId> rsaIds = Arrays.asList(
147: new ServiceId[] {
148: new ServiceId("Signature", "NONEwithRSA"),
149: new ServiceId("Cipher", "RSA/ECB/PKCS1Padding"),
150: new ServiceId("Cipher", "RSA/ECB"),
151: new ServiceId("Cipher", "RSA//PKCS1Padding"),
152: new ServiceId("Cipher", "RSA"),
153: }
154: );
155:
156: /**
157: * Returns a Signature object that implements the specified signature
158: * algorithm.
159: *
160: * <p> This method traverses the list of registered security Providers,
161: * starting with the most preferred Provider.
162: * A new Signature object encapsulating the
163: * SignatureSpi implementation from the first
164: * Provider that supports the specified algorithm is returned.
165: *
166: * <p> Note that the list of registered providers may be retrieved via
167: * the {@link Security#getProviders() Security.getProviders()} method.
168: *
169: * @param algorithm the standard name of the algorithm requested.
170: * See Appendix A in the <a href=
171: * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
172: * Java Cryptography Architecture API Specification & Reference </a>
173: * for information about standard algorithm names.
174: *
175: * @return the new Signature object.
176: *
177: * @exception NoSuchAlgorithmException if no Provider supports a
178: * Signature implementation for the
179: * specified algorithm.
180: *
181: * @see Provider
182: */
183: public static Signature getInstance(String algorithm)
184: throws NoSuchAlgorithmException {
185: List list;
186: if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
187: list = GetInstance.getServices(rsaIds);
188: } else {
189: list = GetInstance.getServices("Signature", algorithm);
190: }
191: Iterator t = list.iterator();
192: if (t.hasNext() == false) {
193: throw new NoSuchAlgorithmException
194: (algorithm + " Signature not available");
195: }
196: // try services until we find an Spi or a working Signature subclass
197: NoSuchAlgorithmException failure;
198: do {
199: Service s = (Service)t.next();
200: if (isSpi(s)) {
201: return new Delegate(s, t, algorithm);
202: } else {
203: // must be a subclass of Signature, disable dynamic selection
204: try {
205: Instance instance =
206: GetInstance.getInstance(s, SignatureSpi.class);
207: return getInstance(instance, algorithm);
208: } catch (NoSuchAlgorithmException e) {
209: failure = e;
210: }
211: }
212: } while (t.hasNext());
213: throw failure;
214: }
215:
216: private static Signature getInstance(Instance instance, String algorithm) {
217: Signature sig;
218: if (instance.impl instanceof Signature) {
219: sig = (Signature)instance.impl;
220: } else {
221: SignatureSpi spi = (SignatureSpi)instance.impl;
222: sig = new Delegate(spi, algorithm);
223: }
224: sig.provider = instance.provider;
225: return sig;
226: }
227:
228: private final static Map<String,Boolean> signatureInfo;
229:
230: static {
231: signatureInfo = new ConcurrentHashMap<String,Boolean>();
232: Boolean TRUE = Boolean.TRUE;
233: // pre-initialize with values for our SignatureSpi implementations
234: signatureInfo.put("sun.security.provider.DSA$RawDSA", TRUE);
235: signatureInfo.put("sun.security.provider.DSA$SHA1withDSA", TRUE);
236: signatureInfo.put("sun.security.rsa.RSASignature$MD2withRSA", TRUE);
237: signatureInfo.put("sun.security.rsa.RSASignature$MD5withRSA", TRUE);
238: signatureInfo.put("sun.security.rsa.RSASignature$SHA1withRSA", TRUE);
239: signatureInfo.put("sun.security.rsa.RSASignature$SHA256withRSA", TRUE);
240: signatureInfo.put("sun.security.rsa.RSASignature$SHA384withRSA", TRUE);
241: signatureInfo.put("sun.security.rsa.RSASignature$SHA512withRSA", TRUE);
242: signatureInfo.put("com.sun.net.ssl.internal.ssl.RSASignature", TRUE);
243: signatureInfo.put("sun.security.pkcs11.P11Signature", TRUE);
244: }
245:
246: private static boolean isSpi(Service s) {
247: if (s.getType().equals("Cipher")) {
248: // must be a CipherSpi, which we can wrap with the CipherAdapter
249: return true;
250: }
251: String className = s.getClassName();
252: Boolean result = signatureInfo.get(className);
253: if (result == null) {
254: try {
255: Object instance = s.newInstance(null);
256: // Signature extends SignatureSpi
257: // so it is a "real" Spi if it is an
258: // instance of SignatureSpi but not Signature
259: boolean r = (instance instanceof SignatureSpi)
260: && (instance instanceof Signature == false);
261: if ((debug != null) && (r == false)) {
262: debug.println("Not a SignatureSpi " + className);
263: debug.println("Delayed provider selection may not be "
264: + "available for algorithm " + s.getAlgorithm());
265: }
266: result = Boolean.valueOf(r);
267: signatureInfo.put(className, result);
268: } catch (Exception e) {
269: // something is wrong, assume not an SPI
270: return false;
271: }
272: }
273: return result.booleanValue();
274: }
275:
276: /**
277: * Returns a Signature object that implements the specified signature
278: * algorithm.
279: *
280: * <p> A new Signature object encapsulating the
281: * SignatureSpi implementation from the specified provider
282: * is returned. The specified provider must be registered
283: * in the security provider list.
284: *
285: * <p> Note that the list of registered providers may be retrieved via
286: * the {@link Security#getProviders() Security.getProviders()} method.
287: *
288: * @param algorithm the name of the algorithm requested.
289: * See Appendix A in the <a href=
290: * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
291: * Java Cryptography Architecture API Specification & Reference </a>
292: * for information about standard algorithm names.
293: *
294: * @param provider the name of the provider.
295: *
296: * @return the new Signature object.
297: *
298: * @exception NoSuchAlgorithmException if a SignatureSpi
299: * implementation for the specified algorithm is not
300: * available from the specified provider.
301: *
302: * @exception NoSuchProviderException if the specified provider is not
303: * registered in the security provider list.
304: *
305: * @exception IllegalArgumentException if the provider name is null
306: * or empty.
307: *
308: * @see Provider
309: */
310: public static Signature getInstance(String algorithm, String provider)
311: throws NoSuchAlgorithmException, NoSuchProviderException {
312: if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
313: // exception compatibility with existing code
314: if ((provider == null) || (provider.length() == 0)) {
315: throw new IllegalArgumentException("missing provider");
316: }
317: Provider p = Security.getProvider(provider);
318: if (p == null) {
319: throw new NoSuchProviderException
320: ("no such provider: " + provider);
321: }
322: return getInstanceRSA(p);
323: }
324: Instance instance = GetInstance.getInstance
325: ("Signature", SignatureSpi.class, algorithm, provider);
326: return getInstance(instance, algorithm);
327: }
328:
329: /**
330: * Returns a Signature object that implements the specified
331: * signature algorithm.
332: *
333: * <p> A new Signature object encapsulating the
334: * SignatureSpi implementation from the specified Provider
335: * object is returned. Note that the specified Provider object
336: * does not have to be registered in the provider list.
337: *
338: * @param algorithm the name of the algorithm requested.
339: * See Appendix A in the <a href=
340: * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
341: * Java Cryptography Architecture API Specification & Reference </a>
342: * for information about standard algorithm names.
343: *
344: * @param provider the provider.
345: *
346: * @return the new Signature object.
347: *
348: * @exception NoSuchAlgorithmException if a SignatureSpi
349: * implementation for the specified algorithm is not available
350: * from the specified Provider object.
351: *
352: * @exception IllegalArgumentException if the provider is null.
353: *
354: * @see Provider
355: *
356: * @since 1.4
357: */
358: public static Signature getInstance(String algorithm, Provider provider)
359: throws NoSuchAlgorithmException {
360: if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
361: // exception compatibility with existing code
362: if (provider == null) {
363: throw new IllegalArgumentException("missing provider");
364: }
365: return getInstanceRSA(provider);
366: }
367: Instance instance = GetInstance.getInstance
368: ("Signature", SignatureSpi.class, algorithm, provider);
369: return getInstance(instance, algorithm);
370: }
371:
372: // return an implementation for NONEwithRSA, which is a special case
373: // because of the Cipher.RSA/ECB/PKCS1Padding compatibility wrapper
374: private static Signature getInstanceRSA(Provider p)
375: throws NoSuchAlgorithmException {
376: // try Signature first
377: Service s = p.getService("Signature", RSA_SIGNATURE);
378: if (s != null) {
379: Instance instance = GetInstance.getInstance(s, SignatureSpi.class);
380: return getInstance(instance, RSA_SIGNATURE);
381: }
382: // check Cipher
383: try {
384: Cipher c = Cipher.getInstance(RSA_CIPHER, p);
385: return new Delegate(new CipherAdapter(c), RSA_SIGNATURE);
386: } catch (GeneralSecurityException e) {
387: // throw Signature style exception message to avoid confusion,
388: // but append Cipher exception as cause
389: throw new NoSuchAlgorithmException("no such algorithm: "
390: + RSA_SIGNATURE + " for provider " + p.getName(), e);
391: }
392: }
393:
394: /**
395: * Returns the provider of this signature object.
396: *
397: * @return the provider of this signature object
398: */
399: public final Provider getProvider() {
400: chooseFirstProvider();
401: return this.provider;
402: }
403:
404: void chooseFirstProvider() {
405: // empty, overridden in Delegate
406: }
407:
408: /**
409: * Initializes this object for verification. If this method is called
410: * again with a different argument, it negates the effect
411: * of this call.
412: *
413: * @param publicKey the public key of the identity whose signature is
414: * going to be verified.
415: *
416: * @exception InvalidKeyException if the key is invalid.
417: */
418: public final void initVerify(PublicKey publicKey)
419: throws InvalidKeyException {
420: engineInitVerify(publicKey);
421: state = VERIFY;
422: }
423:
424: /**
425: * Initializes this object for verification, using the public key from
426: * the given certificate.
427: * <p>If the certificate is of type X.509 and has a <i>key usage</i>
428: * extension field marked as critical, and the value of the <i>key usage</i>
429: * extension field implies that the public key in
430: * the certificate and its corresponding private key are not
431: * supposed to be used for digital signatures, an
432: * <code>InvalidKeyException</code> is thrown.
433: *
434: * @param certificate the certificate of the identity whose signature is
435: * going to be verified.
436: *
437: * @exception InvalidKeyException if the public key in the certificate
438: * is not encoded properly or does not include required parameter
439: * information or cannot be used for digital signature purposes.
440: * @since 1.3
441: */
442: public final void initVerify(Certificate certificate)
443: throws InvalidKeyException {
444: // If the certificate is of type X509Certificate,
445: // we should check whether it has a Key Usage
446: // extension marked as critical.
447: if (certificate instanceof java.security.cert.X509Certificate) {
448: // Check whether the cert has a key usage extension
449: // marked as a critical extension.
450: // The OID for KeyUsage extension is 2.5.29.15.
451: X509Certificate cert = (X509Certificate)certificate;
452: Set critSet = cert.getCriticalExtensionOIDs();
453:
454: if (critSet != null && !critSet.isEmpty()
455: && critSet.contains("2.5.29.15")) {
456: boolean[] keyUsageInfo = cert.getKeyUsage();
457: // keyUsageInfo[0] is for digitalSignature.
458: if ((keyUsageInfo != null) && (keyUsageInfo[0] == false))
459: throw new InvalidKeyException("Wrong key usage");
460: }
461: }
462:
463: PublicKey publicKey = certificate.getPublicKey();
464: engineInitVerify(publicKey);
465: state = VERIFY;
466: }
467:
468: /**
469: * Initialize this object for signing. If this method is called
470: * again with a different argument, it negates the effect
471: * of this call.
472: *
473: * @param privateKey the private key of the identity whose signature
474: * is going to be generated.
475: *
476: * @exception InvalidKeyException if the key is invalid.
477: */
478: public final void initSign(PrivateKey privateKey)
479: throws InvalidKeyException {
480: engineInitSign(privateKey);
481: state = SIGN;
482: }
483:
484: /**
485: * Initialize this object for signing. If this method is called
486: * again with a different argument, it negates the effect
487: * of this call.
488: *
489: * @param privateKey the private key of the identity whose signature
490: * is going to be generated.
491: *
492: * @param random the source of randomness for this signature.
493: *
494: * @exception InvalidKeyException if the key is invalid.
495: */
496: public final void initSign(PrivateKey privateKey, SecureRandom random)
497: throws InvalidKeyException {
498: engineInitSign(privateKey, random);
499: state = SIGN;
500: }
501:
502: /**
503: * Returns the signature bytes of all the data updated.
504: * The format of the signature depends on the underlying
505: * signature scheme.
506: *
507: * <p>A call to this method resets this signature object to the state
508: * it was in when previously initialized for signing via a
509: * call to <code>initSign(PrivateKey)</code>. That is, the object is
510: * reset and available to generate another signature from the same
511: * signer, if desired, via new calls to <code>update</code> and
512: * <code>sign</code>.
513: *
514: * @return the signature bytes of the signing operation's result.
515: *
516: * @exception SignatureException if this signature object is not
517: * initialized properly or if this signature algorithm is unable to
518: * process the input data provided.
519: */
520: public final byte[] sign() throws SignatureException {
521: if (state == SIGN) {
522: return engineSign();
523: }
524: throw new SignatureException("object not initialized for " +
525: "signing");
526: }
527:
528: /**
529: * Finishes the signature operation and stores the resulting signature
530: * bytes in the provided buffer <code>outbuf</code>, starting at
531: * <code>offset</code>.
532: * The format of the signature depends on the underlying
533: * signature scheme.
534: *
535: * <p>This signature object is reset to its initial state (the state it
536: * was in after a call to one of the <code>initSign</code> methods) and
537: * can be reused to generate further signatures with the same private key.
538: *
539: * @param outbuf buffer for the signature result.
540: *
541: * @param offset offset into <code>outbuf</code> where the signature is
542: * stored.
543: *
544: * @param len number of bytes within <code>outbuf</code> allotted for the
545: * signature.
546: *
547: * @return the number of bytes placed into <code>outbuf</code>.
548: *
549: * @exception SignatureException if this signature object is not
550: * initialized properly, if this signature algorithm is unable to
551: * process the input data provided, or if <code>len</code> is less
552: * than the actual signature length.
553: *
554: * @since 1.2
555: */
556: public final int sign(byte[] outbuf, int offset, int len)
557: throws SignatureException {
558: if (outbuf == null) {
559: throw new IllegalArgumentException("No output buffer given");
560: }
561: if (outbuf.length - offset < len) {
562: throw new IllegalArgumentException
563: ("Output buffer too small for specified offset and length");
564: }
565: if (state != SIGN) {
566: throw new SignatureException("object not initialized for " +
567: "signing");
568: }
569: return engineSign(outbuf, offset, len);
570: }
571:
572: /**
573: * Verifies the passed-in signature.
574: *
575: * <p>A call to this method resets this signature object to the state
576: * it was in when previously initialized for verification via a
577: * call to <code>initVerify(PublicKey)</code>. That is, the object is
578: * reset and available to verify another signature from the identity
579: * whose public key was specified in the call to <code>initVerify</code>.
580: *
581: * @param signature the signature bytes to be verified.
582: *
583: * @return true if the signature was verified, false if not.
584: *
585: * @exception SignatureException if this signature object is not
586: * initialized properly, the passed-in signature is improperly
587: * encoded or of the wrong type, if this signature algorithm is unable to
588: * process the input data provided, etc.
589: */
590: public final boolean verify(byte[] signature) throws SignatureException {
591: if (state == VERIFY) {
592: return engineVerify(signature);
593: }
594: throw new SignatureException("object not initialized for " +
595: "verification");
596: }
597:
598: /**
599: * Verifies the passed-in signature in the specified array
600: * of bytes, starting at the specified offset.
601: *
602: * <p>A call to this method resets this signature object to the state
603: * it was in when previously initialized for verification via a
604: * call to <code>initVerify(PublicKey)</code>. That is, the object is
605: * reset and available to verify another signature from the identity
606: * whose public key was specified in the call to <code>initVerify</code>.
607: *
608: *
609: * @param signature the signature bytes to be verified.
610: * @param offset the offset to start from in the array of bytes.
611: * @param length the number of bytes to use, starting at offset.
612: *
613: * @return true if the signature was verified, false if not.
614: *
615: * @exception SignatureException if this signature object is not
616: * initialized properly, the passed-in signature is improperly
617: * encoded or of the wrong type, if this signature algorithm is unable to
618: * process the input data provided, etc.
619: * @exception IllegalArgumentException if the <code>signature</code>
620: * byte array is null, or the <code>offset</code> or <code>length</code>
621: * is less than 0, or the sum of the <code>offset</code> and
622: * <code>length</code> is greater than the length of the
623: * <code>signature</code> byte array.
624: * @since 1.4
625: */
626: public final boolean verify(byte[] signature, int offset, int length)
627: throws SignatureException {
628: if (state == VERIFY) {
629: if ((signature == null) || (offset < 0) || (length < 0) ||
630: (offset + length > signature.length)) {
631: throw new IllegalArgumentException("Bad arguments");
632: }
633:
634: return engineVerify(signature, offset, length);
635: }
636: throw new SignatureException("object not initialized for " +
637: "verification");
638: }
639:
640: /**
641: * Updates the data to be signed or verified by a byte.
642: *
643: * @param b the byte to use for the update.
644: *
645: * @exception SignatureException if this signature object is not
646: * initialized properly.
647: */
648: public final void update(byte b) throws SignatureException {
649: if (state == VERIFY || state == SIGN) {
650: engineUpdate(b);
651: } else {
652: throw new SignatureException("object not initialized for "
653: + "signature or verification");
654: }
655: }
656:
657: /**
658: * Updates the data to be signed or verified, using the specified
659: * array of bytes.
660: *
661: * @param data the byte array to use for the update.
662: *
663: * @exception SignatureException if this signature object is not
664: * initialized properly.
665: */
666: public final void update(byte[] data) throws SignatureException {
667: update(data, 0, data.length);
668: }
669:
670: /**
671: * Updates the data to be signed or verified, using the specified
672: * array of bytes, starting at the specified offset.
673: *
674: * @param data the array of bytes.
675: * @param off the offset to start from in the array of bytes.
676: * @param len the number of bytes to use, starting at offset.
677: *
678: * @exception SignatureException if this signature object is not
679: * initialized properly.
680: */
681: public final void update(byte[] data, int off, int len)
682: throws SignatureException {
683: if (state == SIGN || state == VERIFY) {
684: engineUpdate(data, off, len);
685: } else {
686: throw new SignatureException("object not initialized for "
687: + "signature or verification");
688: }
689: }
690:
691: /**
692: * Updates the data to be signed or verified using the specified
693: * ByteBuffer. Processes the <code>data.remaining()</code> bytes
694: * starting at at <code>data.position()</code>.
695: * Upon return, the buffer's position will be equal to its limit;
696: * its limit will not have changed.
697: *
698: * @param data the ByteBuffer
699: *
700: * @exception SignatureException if this signature object is not
701: * initialized properly.
702: * @since 1.5
703: */
704: public final void update(ByteBuffer data) throws SignatureException {
705: if ((state != SIGN) && (state != VERIFY)) {
706: throw new SignatureException("object not initialized for "
707: + "signature or verification");
708: }
709: if (data == null) {
710: throw new NullPointerException();
711: }
712: engineUpdate(data);
713: }
714:
715: /**
716: * Returns the name of the algorithm for this signature object.
717: *
718: * @return the name of the algorithm for this signature object.
719: */
720: public final String getAlgorithm() {
721: return this.algorithm;
722: }
723:
724: /**
725: * Returns a string representation of this signature object,
726: * providing information that includes the state of the object
727: * and the name of the algorithm used.
728: *
729: * @return a string representation of this signature object.
730: */
731: public String toString() {
732: String initState = "";
733: switch (state) {
734: case UNINITIALIZED:
735: initState = "<not initialized>";
736: break;
737: case VERIFY:
738: initState = "<initialized for verifying>";
739: break;
740: case SIGN:
741: initState = "<initialized for signing>";
742: break;
743: }
744: return "Signature object: " + getAlgorithm() + initState;
745: }
746:
747: /**
748: * Sets the specified algorithm parameter to the specified value.
749: * This method supplies a general-purpose mechanism through
750: * which it is possible to set the various parameters of this object.
751: * A parameter may be any settable parameter for the algorithm, such as
752: * a parameter size, or a source of random bits for signature generation
753: * (if appropriate), or an indication of whether or not to perform
754: * a specific but optional computation. A uniform algorithm-specific
755: * naming scheme for each parameter is desirable but left unspecified
756: * at this time.
757: *
758: * @param param the string identifier of the parameter.
759: * @param value the parameter value.
760: *
761: * @exception InvalidParameterException if <code>param</code> is an
762: * invalid parameter for this signature algorithm engine,
763: * the parameter is already set
764: * and cannot be set again, a security exception occurs, and so on.
765: *
766: * @see #getParameter
767: *
768: * @deprecated Use
769: * {@link #setParameter(java.security.spec.AlgorithmParameterSpec)
770: * setParameter}.
771: */
772: @Deprecated
773: public final void setParameter(String param, Object value)
774: throws InvalidParameterException {
775: engineSetParameter(param, value);
776: }
777:
778: /**
779: * Initializes this signature engine with the specified parameter set.
780: *
781: * @param params the parameters
782: *
783: * @exception InvalidAlgorithmParameterException if the given parameters
784: * are inappropriate for this signature engine
785: *
786: * @see #getParameters
787: */
788: public final void setParameter(AlgorithmParameterSpec params)
789: throws InvalidAlgorithmParameterException {
790: engineSetParameter(params);
791: }
792:
793: /**
794: * Returns the parameters used with this signature object.
795: *
796: * <p>The returned parameters may be the same that were used to initialize
797: * this signature, or may contain a combination of default and randomly
798: * generated parameter values used by the underlying signature
799: * implementation if this signature requires algorithm parameters but
800: * was not initialized with any.
801: *
802: * @return the parameters used with this signature, or null if this
803: * signature does not use any parameters.
804: *
805: * @see #setParameter(AlgorithmParameterSpec)
806: * @since 1.4
807: */
808: public final AlgorithmParameters getParameters() {
809: return engineGetParameters();
810: }
811:
812: /**
813: * Gets the value of the specified algorithm parameter. This method
814: * supplies a general-purpose mechanism through which it is possible to
815: * get the various parameters of this object. A parameter may be any
816: * settable parameter for the algorithm, such as a parameter size, or
817: * a source of random bits for signature generation (if appropriate),
818: * or an indication of whether or not to perform a specific but optional
819: * computation. A uniform algorithm-specific naming scheme for each
820: * parameter is desirable but left unspecified at this time.
821: *
822: * @param param the string name of the parameter.
823: *
824: * @return the object that represents the parameter value, or null if
825: * there is none.
826: *
827: * @exception InvalidParameterException if <code>param</code> is an invalid
828: * parameter for this engine, or another exception occurs while
829: * trying to get this parameter.
830: *
831: * @see #setParameter(String, Object)
832: *
833: * @deprecated
834: */
835: @Deprecated
836: public final Object getParameter(String param)
837: throws InvalidParameterException {
838: return engineGetParameter(param);
839: }
840:
841: /**
842: * Returns a clone if the implementation is cloneable.
843: *
844: * @return a clone if the implementation is cloneable.
845: *
846: * @exception CloneNotSupportedException if this is called
847: * on an implementation that does not support <code>Cloneable</code>.
848: */
849: public Object clone() throws CloneNotSupportedException {
850: if (this instanceof Cloneable) {
851: return super.clone();
852: } else {
853: throw new CloneNotSupportedException();
854: }
855: }
856:
857: /*
858: * The following class allows providers to extend from SignatureSpi
859: * rather than from Signature. It represents a Signature with an
860: * encapsulated, provider-supplied SPI object (of type SignatureSpi).
861: * If the provider implementation is an instance of SignatureSpi, the
862: * getInstance() methods above return an instance of this class, with
863: * the SPI object encapsulated.
864: *
865: * Note: All SPI methods from the original Signature class have been
866: * moved up the hierarchy into a new class (SignatureSpi), which has
867: * been interposed in the hierarchy between the API (Signature)
868: * and its original parent (Object).
869: */
870:
871: private static class Delegate extends Signature {
872:
873: // The provider implementation (delegate)
874: // filled in once the provider is selected
875: private SignatureSpi sigSpi;
876:
877: // lock for mutex during provider selection
878: private final Object lock;
879:
880: // next service to try in provider selection
881: // null once provider is selected
882: private Service firstService;
883:
884: // remaining services to try in provider selection
885: // null once provider is selected
886: private Iterator serviceIterator;
887:
888: // constructor
889: Delegate(SignatureSpi sigSpi, String algorithm) {
890: super(algorithm);
891: this.sigSpi = sigSpi;
892: this.lock = null; // no lock needed
893: }
894:
895: // used with delayed provider selection
896: Delegate(Service service, Iterator iterator, String algorithm) {
897: super(algorithm);
898: this.firstService = service;
899: this.serviceIterator = iterator;
900: this.lock = new Object();
901: }
902:
903: /**
904: * Returns a clone if the delegate is cloneable.
905: *
906: * @return a clone if the delegate is cloneable.
907: *
908: * @exception CloneNotSupportedException if this is called on a
909: * delegate that does not support <code>Cloneable</code>.
910: */
911: public Object clone() throws CloneNotSupportedException {
912: chooseFirstProvider();
913: if (sigSpi instanceof Cloneable) {
914: SignatureSpi sigSpiClone = (SignatureSpi)sigSpi.clone();
915: // Because 'algorithm' and 'provider' are private
916: // members of our supertype, we must perform a cast to
917: // access them.
918: Signature that =
919: new Delegate(sigSpiClone, ((Signature)this).algorithm);
920: that.provider = ((Signature)this).provider;
921: return that;
922: } else {
923: throw new CloneNotSupportedException();
924: }
925: }
926:
927: private static SignatureSpi newInstance(Service s)
928: throws NoSuchAlgorithmException {
929: if (s.getType().equals("Cipher")) {
930: // must be NONEwithRSA
931: try {
932: Cipher c = Cipher.getInstance(RSA_CIPHER, s.getProvider());
933: return new CipherAdapter(c);
934: } catch (NoSuchPaddingException e) {
935: throw new NoSuchAlgorithmException(e);
936: }
937: } else {
938: Object o = s.newInstance(null);
939: if (o instanceof SignatureSpi == false) {
940: throw new NoSuchAlgorithmException
941: ("Not a SignatureSpi: " + o.getClass().getName());
942: }
943: return (SignatureSpi)o;
944: }
945: }
946:
947: // max number of debug warnings to print from chooseFirstProvider()
948: private static int warnCount = 10;
949:
950: /**
951: * Choose the Spi from the first provider available. Used if
952: * delayed provider selection is not possible because initSign()/
953: * initVerify() is not the first method called.
954: */
955: void chooseFirstProvider() {
956: if (sigSpi != null) {
957: return;
958: }
959: synchronized (lock) {
960: if (sigSpi != null) {
961: return;
962: }
963: if (debug != null) {
964: int w = --warnCount;
965: if (w >= 0) {
966: debug.println("Signature.init() not first method "
967: + "called, disabling delayed provider selection");
968: if (w == 0) {
969: debug.println("Further warnings of this type will "
970: + "be suppressed");
971: }
972: new Exception("Call trace").printStackTrace();
973: }
974: }
975: Exception lastException = null;
976: while ((firstService != null) || serviceIterator.hasNext()) {
977: Service s;
978: if (firstService != null) {
979: s = firstService;
980: firstService = null;
981: } else {
982: s = (Service)serviceIterator.next();
983: }
984: if (isSpi(s) == false) {
985: continue;
986: }
987: try {
988: sigSpi = newInstance(s);
989: provider = s.getProvider();
990: // not needed any more
991: firstService = null;
992: serviceIterator = null;
993: return;
994: } catch (NoSuchAlgorithmException e) {
995: lastException = e;
996: }
997: }
998: ProviderException e = new ProviderException
999: ("Could not construct SignatureSpi instance");
1000: if (lastException != null) {
1001: e.initCause(lastException);
1002: }
1003: throw e;
1004: }
1005: }
1006:
1007: private void chooseProvider(int type, Key key, SecureRandom random)
1008: throws InvalidKeyException {
1009: synchronized (lock) {
1010: if (sigSpi != null) {
1011: init(sigSpi, type, key, random);
1012: return;
1013: }
1014: Exception lastException = null;
1015: while ((firstService != null) || serviceIterator.hasNext()) {
1016: Service s;
1017: if (firstService != null) {
1018: s = firstService;
1019: firstService = null;
1020: } else {
1021: s = (Service)serviceIterator.next();
1022: }
1023: // if provider says it does not support this key, ignore it
1024: if (s.supportsParameter(key) == false) {
1025: continue;
1026: }
1027: // if instance is not a SignatureSpi, ignore it
1028: if (isSpi(s) == false) {
1029: continue;
1030: }
1031: try {
1032: SignatureSpi spi = newInstance(s);
1033: init(spi, type, key, random);
1034: provider = s.getProvider();
1035: sigSpi = spi;
1036: firstService = null;
1037: serviceIterator = null;
1038: return;
1039: } catch (Exception e) {
1040: // NoSuchAlgorithmException from newInstance()
1041: // InvalidKeyException from init()
1042: // RuntimeException (ProviderException) from init()
1043: if (lastException == null) {
1044: lastException = e;
1045: }
1046: }
1047: }
1048: // no working provider found, fail
1049: if (lastException instanceof InvalidKeyException) {
1050: throw (InvalidKeyException)lastException;
1051: }
1052: if (lastException instanceof RuntimeException) {
1053: throw (RuntimeException)lastException;
1054: }
1055: String k = (key != null) ? key.getClass().getName() : "(null)";
1056: throw new InvalidKeyException
1057: ("No installed provider supports this key: "
1058: + k, lastException);
1059: }
1060: }
1061:
1062: private final static int I_PUB = 1;
1063: private final static int I_PRIV = 2;
1064: private final static int I_PRIV_SR = 3;
1065:
1066: private void init(SignatureSpi spi, int type, Key key,
1067: SecureRandom random) throws InvalidKeyException {
1068: switch (type) {
1069: case I_PUB:
1070: spi.engineInitVerify((PublicKey)key);
1071: break;
1072: case I_PRIV:
1073: spi.engineInitSign((PrivateKey)key);
1074: break;
1075: case I_PRIV_SR:
1076: spi.engineInitSign((PrivateKey)key, random);
1077: break;
1078: default:
1079: throw new AssertionError("Internal error: " + type);
1080: }
1081: }
1082:
1083: protected void engineInitVerify(PublicKey publicKey)
1084: throws InvalidKeyException {
1085: if (sigSpi != null) {
1086: sigSpi.engineInitVerify(publicKey);
1087: } else {
1088: chooseProvider(I_PUB, publicKey, null);
1089: }
1090: }
1091:
1092: protected void engineInitSign(PrivateKey privateKey)
1093: throws InvalidKeyException {
1094: if (sigSpi != null) {
1095: sigSpi.engineInitSign(privateKey);
1096: } else {
1097: chooseProvider(I_PRIV, privateKey, null);
1098: }
1099: }
1100:
1101: protected void engineInitSign(PrivateKey privateKey, SecureRandom sr)
1102: throws InvalidKeyException {
1103: if (sigSpi != null) {
1104: sigSpi.engineInitSign(privateKey, sr);
1105: } else {
1106: chooseProvider(I_PRIV_SR, privateKey, sr);
1107: }
1108: }
1109:
1110: protected void engineUpdate(byte b) throws SignatureException {
1111: chooseFirstProvider();
1112: sigSpi.engineUpdate(b);
1113: }
1114:
1115: protected void engineUpdate(byte[] b, int off, int len)
1116: throws SignatureException {
1117: chooseFirstProvider();
1118: sigSpi.engineUpdate(b, off, len);
1119: }
1120:
1121: protected void engineUpdate(ByteBuffer data) {
1122: chooseFirstProvider();
1123: sigSpi.engineUpdate(data);
1124: }
1125:
1126: protected byte[] engineSign() throws SignatureException {
1127: chooseFirstProvider();
1128: return sigSpi.engineSign();
1129: }
1130:
1131: protected int engineSign(byte[] outbuf, int offset, int len)
1132: throws SignatureException {
1133: chooseFirstProvider();
1134: return sigSpi.engineSign(outbuf, offset, len);
1135: }
1136:
1137: protected boolean engineVerify(byte[] sigBytes)
1138: throws SignatureException {
1139: chooseFirstProvider();
1140: return sigSpi.engineVerify(sigBytes);
1141: }
1142:
1143: protected boolean engineVerify(byte[] sigBytes, int offset, int length)
1144: throws SignatureException {
1145: chooseFirstProvider();
1146: return sigSpi.engineVerify(sigBytes, offset, length);
1147: }
1148:
1149: protected void engineSetParameter(String param, Object value)
1150: throws InvalidParameterException {
1151: chooseFirstProvider();
1152: sigSpi.engineSetParameter(param, value);
1153: }
1154:
1155: protected void engineSetParameter(AlgorithmParameterSpec params)
1156: throws InvalidAlgorithmParameterException {
1157: chooseFirstProvider();
1158: sigSpi.engineSetParameter(params);
1159: }
1160:
1161: protected Object engineGetParameter(String param)
1162: throws InvalidParameterException {
1163: chooseFirstProvider();
1164: return sigSpi.engineGetParameter(param);
1165: }
1166:
1167: protected AlgorithmParameters engineGetParameters() {
1168: chooseFirstProvider();
1169: return sigSpi.engineGetParameters();
1170: }
1171: }
1172:
1173: // adapter for RSA/ECB/PKCS1Padding ciphers
1174: private static class CipherAdapter extends SignatureSpi {
1175:
1176: private final Cipher cipher;
1177:
1178: private ByteArrayOutputStream data;
1179:
1180: CipherAdapter(Cipher cipher) {
1181: this.cipher = cipher;
1182: }
1183:
1184: protected void engineInitVerify(PublicKey publicKey)
1185: throws InvalidKeyException {
1186: cipher.init(Cipher.DECRYPT_MODE, publicKey);
1187: if (data == null) {
1188: data = new ByteArrayOutputStream(128);
1189: } else {
1190: data.reset();
1191: }
1192: }
1193:
1194: protected void engineInitSign(PrivateKey privateKey)
1195: throws InvalidKeyException {
1196: cipher.init(Cipher.ENCRYPT_MODE, privateKey);
1197: data = null;
1198: }
1199:
1200: protected void engineInitSign(PrivateKey privateKey,
1201: SecureRandom random) throws InvalidKeyException {
1202: cipher.init(Cipher.ENCRYPT_MODE, privateKey, random);
1203: data = null;
1204: }
1205:
1206: protected void engineUpdate(byte b) throws SignatureException {
1207: engineUpdate(new byte[] {b}, 0, 1);
1208: }
1209:
1210: protected void engineUpdate(byte[] b, int off, int len)
1211: throws SignatureException {
1212: if (data != null) {
1213: data.write(b, off, len);
1214: return;
1215: }
1216: byte[] out = cipher.update(b, off, len);
1217: if ((out != null) && (out.length != 0)) {
1218: throw new SignatureException
1219: ("Cipher unexpectedly returned data");
1220: }
1221: }
1222:
1223: protected byte[] engineSign() throws SignatureException {
1224: try {
1225: return cipher.doFinal();
1226: } catch (IllegalBlockSizeException e) {
1227: throw new SignatureException("doFinal() failed", e);
1228: } catch (BadPaddingException e) {
1229: throw new SignatureException("doFinal() failed", e);
1230: }
1231: }
1232:
1233: protected boolean engineVerify(byte[] sigBytes)
1234: throws SignatureException {
1235: try {
1236: byte[] out = cipher.doFinal(sigBytes);
1237: byte[] dataBytes = data.toByteArray();
1238: data.reset();
1239: return Arrays.equals(out, dataBytes);
1240: } catch (BadPaddingException e) {
1241: // e.g. wrong public key used
1242: // return false rather than throwing exception
1243: return false;
1244: } catch (IllegalBlockSizeException e) {
1245: throw new SignatureException("doFinal() failed", e);
1246: }
1247: }
1248:
1249: protected void engineSetParameter(String param, Object value)
1250: throws InvalidParameterException {
1251: throw new InvalidParameterException("Parameters not supported");
1252: }
1253:
1254: protected Object engineGetParameter(String param)
1255: throws InvalidParameterException {
1256: throw new InvalidParameterException("Parameters not supported");
1257: }
1258:
1259: }
1260:
1261: }
1262: