java.security.Signature: NaN%

Overview

Search Parameters

EvoSuite Parameters

Old Parameters

Statistics

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 &amp; 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 &amp; 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 &amp; 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 &amp; 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: