1 /*
2  * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */

25
26 package java.security;
27
28 import java.security.spec.AlgorithmParameterSpec;
29 import java.util.*;
30 import java.util.concurrent.ConcurrentHashMap;
31 import java.io.*;
32 import java.security.cert.Certificate;
33 import java.security.cert.X509Certificate;
34
35 import java.nio.ByteBuffer;
36
37 import java.security.Provider.Service;
38
39 import javax.crypto.Cipher;
40 import javax.crypto.IllegalBlockSizeException;
41 import javax.crypto.BadPaddingException;
42 import javax.crypto.NoSuchPaddingException;
43 import jdk.internal.misc.JavaSecuritySignatureAccess;
44 import jdk.internal.misc.SharedSecrets;
45
46 import sun.security.util.Debug;
47 import sun.security.jca.*;
48 import sun.security.jca.GetInstance.Instance;
49
50 /**
51  * The Signature class is used to provide applications the functionality
52  * of a digital signature algorithm. Digital signatures are used for
53  * authentication and integrity assurance of digital data.
54  *
55  * <p> The signature algorithm can be, among others, the NIST standard
56  * DSA, using DSA and SHA-256. The DSA algorithm using the
57  * SHA-256 message digest algorithm can be specified as {@code SHA256withDSA}.
58  * In the case of RSA the signing algorithm could be specified as, for example,
59  * {@code SHA256withRSA}.
60  * The algorithm name must be specified, as there is no default.
61  *
62  * <p> A Signature object can be used to generate and verify digital
63  * signatures.
64  *
65  * <p> There are three phases to the use of a Signature object for
66  * either signing data or verifying a signature:<ol>
67  *
68  * <li>Initialization, with either
69  *
70  *     <ul>
71  *
72  *     <li>a public key, which initializes the signature for
73  *     verification (see {@link #initVerify(PublicKey) initVerify}), or
74  *
75  *     <li>a private key (and optionally a Secure Random Number Generator),
76  *     which initializes the signature for signing
77  *     (see {@link #initSign(PrivateKey)}
78  *     and {@link #initSign(PrivateKey, SecureRandom)}).
79  *
80  *     </ul>
81  *
82  * <li>Updating
83  *
84  * <p>Depending on the type of initialization, this will update the
85  * bytes to be signed or verified. See the
86  * {@link #update(byte) update} methods.
87  *
88  * <li>Signing or Verifying a signature on all updated bytes. See the
89  * {@link #sign() sign} methods and the {@link #verify(byte[]) verify}
90  * method.
91  *
92  * </ol>
93  *
94  * <p>Note that this class is abstract and extends from
95  * {@code SignatureSpi} for historical reasons.
96  * Application developers should only take notice of the methods defined in
97  * this {@code Signature} class; all the methods in
98  * the superclass are intended for cryptographic service providers who wish to
99  * supply their own implementations of digital signature algorithms.
100  *
101  * <p> Every implementation of the Java platform is required to support the
102  * following standard {@code Signature} algorithms:
103  * <ul>
104  * <li>{@code SHA1withDSA}</li>
105  * <li>{@code SHA256withDSA}</li>
106  * <li>{@code SHA1withRSA}</li>
107  * <li>{@code SHA256withRSA}</li>
108  * </ul>
109  * These algorithms are described in the <a href=
110  * "{@docRoot}/../specs/security/standard-names.html#signature-algorithms">
111  * Signature section</a> of the
112  * Java Security Standard Algorithm Names Specification.
113  * Consult the release documentation for your implementation to see if any
114  * other algorithms are supported.
115  *
116  * @author Benjamin Renaud
117  * @since 1.1
118  *
119  */

120
121 public abstract class Signature extends SignatureSpi {
122
123     static {
124         SharedSecrets.setJavaSecuritySignatureAccess(
125             new JavaSecuritySignatureAccess() {
126                 @Override
127                 public void initVerify(Signature s, PublicKey publicKey,
128                         AlgorithmParameterSpec params)
129                         throws InvalidKeyException,
130                         InvalidAlgorithmParameterException {
131                     s.initVerify(publicKey, params);
132                 }
133                 @Override
134                 public void initVerify(Signature s,
135                         java.security.cert.Certificate certificate,
136                         AlgorithmParameterSpec params)
137                         throws InvalidKeyException,
138                         InvalidAlgorithmParameterException {
139                     s.initVerify(certificate, params);
140                 }
141                 @Override
142                 public void initSign(Signature s, PrivateKey privateKey,
143                         AlgorithmParameterSpec params, SecureRandom random)
144                         throws InvalidKeyException,
145                         InvalidAlgorithmParameterException {
146                     s.initSign(privateKey, params, random);
147                 }
148         });
149     }
150
151     private static final Debug debug =
152                         Debug.getInstance("jca""Signature");
153
154     private static final Debug pdebug =
155                         Debug.getInstance("provider""Provider");
156     private static final boolean skipDebug =
157         Debug.isOn("engine=") && !Debug.isOn("signature");
158
159     /*
160      * The algorithm for this signature object.
161      * This value is used to map an OID to the particular algorithm.
162      * The mapping is done in AlgorithmObject.algOID(String algorithm)
163      */

164     private String algorithm;
165
166     // The provider
167     Provider provider;
168
169     /**
170      * Possible {@link #state} value, signifying that
171      * this signature object has not yet been initialized.
172      */

173     protected static final int UNINITIALIZED = 0;
174
175     /**
176      * Possible {@link #state} value, signifying that
177      * this signature object has been initialized for signing.
178      */

179     protected static final int SIGN = 2;
180
181     /**
182      * Possible {@link #state} value, signifying that
183      * this signature object has been initialized for verification.
184      */

185     protected static final int VERIFY = 3;
186
187     /**
188      * Current state of this signature object.
189      */

190     protected int state = UNINITIALIZED;
191
192     /**
193      * Creates a Signature object for the specified algorithm.
194      *
195      * @param algorithm the standard string name of the algorithm.
196      * See the Signature section in the <a href=
197      * "{@docRoot}/../specs/security/standard-names.html#signature-algorithms">
198      * Java Security Standard Algorithm Names Specification</a>
199      * for information about standard algorithm names.
200      */

201     protected Signature(String algorithm) {
202         this.algorithm = algorithm;
203     }
204
205     // name of the special signature alg
206     private static final String RSA_SIGNATURE = "NONEwithRSA";
207
208     // name of the equivalent cipher alg
209     private static final String RSA_CIPHER = "RSA/ECB/PKCS1Padding";
210
211     // all the services we need to lookup for compatibility with Cipher
212     private static final List<ServiceId> rsaIds = List.of(
213         new ServiceId("Signature""NONEwithRSA"),
214         new ServiceId("Cipher""RSA/ECB/PKCS1Padding"),
215         new ServiceId("Cipher""RSA/ECB"),
216         new ServiceId("Cipher""RSA//PKCS1Padding"),
217         new ServiceId("Cipher""RSA"));
218
219     /**
220      * Returns a Signature object that implements the specified signature
221      * algorithm.
222      *
223      * <p> This method traverses the list of registered security Providers,
224      * starting with the most preferred Provider.
225      * A new Signature object encapsulating the
226      * SignatureSpi implementation from the first
227      * Provider that supports the specified algorithm is returned.
228      *
229      * <p> Note that the list of registered providers may be retrieved via
230      * the {@link Security#getProviders() Security.getProviders()} method.
231      *
232      * @implNote
233      * The JDK Reference Implementation additionally uses the
234      * {@code jdk.security.provider.preferred}
235      * {@link Security#getProperty(String) Security} property to determine
236      * the preferred provider order for the specified algorithm. This
237      * may be different than the order of providers returned by
238      * {@link Security#getProviders() Security.getProviders()}.
239      *
240      * @param algorithm the standard name of the algorithm requested.
241      * See the Signature section in the <a href=
242      * "{@docRoot}/../specs/security/standard-names.html#signature-algorithms">
243      * Java Security Standard Algorithm Names Specification</a>
244      * for information about standard algorithm names.
245      *
246      * @return the new {@code Signature} object
247      *
248      * @throws NoSuchAlgorithmException if no {@code Provider} supports a
249      *         {@code Signature} implementation for the
250      *         specified algorithm
251      *
252      * @throws NullPointerException if {@code algorithm} is {@code null}
253      *
254      * @see Provider
255      */

256     public static Signature getInstance(String algorithm)
257             throws NoSuchAlgorithmException {
258         Objects.requireNonNull(algorithm, "null algorithm name");
259         List<Service> list;
260         if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
261             list = GetInstance.getServices(rsaIds);
262         } else {
263             list = GetInstance.getServices("Signature", algorithm);
264         }
265         Iterator<Service> t = list.iterator();
266         if (t.hasNext() == false) {
267             throw new NoSuchAlgorithmException
268                 (algorithm + " Signature not available");
269         }
270         // try services until we find an Spi or a working Signature subclass
271         NoSuchAlgorithmException failure;
272         do {
273             Service s = t.next();
274             if (isSpi(s)) {
275                 return new Delegate(s, t, algorithm);
276             } else {
277                 // must be a subclass of Signature, disable dynamic selection
278                 try {
279                     Instance instance =
280                         GetInstance.getInstance(s, SignatureSpi.class);
281                     return getInstance(instance, algorithm);
282                 } catch (NoSuchAlgorithmException e) {
283                     failure = e;
284                 }
285             }
286         } while (t.hasNext());
287         throw failure;
288     }
289
290     private static Signature getInstance(Instance instance, String algorithm) {
291         Signature sig;
292         if (instance.impl instanceof Signature) {
293             sig = (Signature)instance.impl;
294             sig.algorithm = algorithm;
295         } else {
296             SignatureSpi spi = (SignatureSpi)instance.impl;
297             sig = new Delegate(spi, algorithm);
298         }
299         sig.provider = instance.provider;
300         return sig;
301     }
302
303     private static final Map<String,Boolean> signatureInfo;
304
305     static {
306         signatureInfo = new ConcurrentHashMap<>();
307         Boolean TRUE = Boolean.TRUE;
308         // pre-initialize with values for our SignatureSpi implementations
309         signatureInfo.put("sun.security.provider.DSA$RawDSA", TRUE);
310         signatureInfo.put("sun.security.provider.DSA$SHA1withDSA", TRUE);
311         signatureInfo.put("sun.security.rsa.RSASignature$MD2withRSA", TRUE);
312         signatureInfo.put("sun.security.rsa.RSASignature$MD5withRSA", TRUE);
313         signatureInfo.put("sun.security.rsa.RSASignature$SHA1withRSA", TRUE);
314         signatureInfo.put("sun.security.rsa.RSASignature$SHA256withRSA", TRUE);
315         signatureInfo.put("sun.security.rsa.RSASignature$SHA384withRSA", TRUE);
316         signatureInfo.put("sun.security.rsa.RSASignature$SHA512withRSA", TRUE);
317         signatureInfo.put("sun.security.rsa.RSAPSSSignature", TRUE);
318         signatureInfo.put("com.sun.net.ssl.internal.ssl.RSASignature", TRUE);
319         signatureInfo.put("sun.security.pkcs11.P11Signature", TRUE);
320     }
321
322     private static boolean isSpi(Service s) {
323         if (s.getType().equals("Cipher")) {
324             // must be a CipherSpi, which we can wrap with the CipherAdapter
325             return true;
326         }
327         String className = s.getClassName();
328         Boolean result = signatureInfo.get(className);
329         if (result == null) {
330             try {
331                 Object instance = s.newInstance(null);
332                 // Signature extends SignatureSpi
333                 // so it is a "real" Spi if it is an
334                 // instance of SignatureSpi but not Signature
335                 boolean r = (instance instanceof SignatureSpi)
336                                 && (instance instanceof Signature == false);
337                 if ((debug != null) && (r == false)) {
338                     debug.println("Not a SignatureSpi " + className);
339                     debug.println("Delayed provider selection may not be "
340                         + "available for algorithm " + s.getAlgorithm());
341                 }
342                 result = Boolean.valueOf(r);
343                 signatureInfo.put(className, result);
344             } catch (Exception e) {
345                 // something is wrong, assume not an SPI
346                 return false;
347             }
348         }
349         return result.booleanValue();
350     }
351
352     /**
353      * Returns a Signature object that implements the specified signature
354      * algorithm.
355      *
356      * <p> A new Signature object encapsulating the
357      * SignatureSpi implementation from the specified provider
358      * is returned.  The specified provider must be registered
359      * in the security provider list.
360      *
361      * <p> Note that the list of registered providers may be retrieved via
362      * the {@link Security#getProviders() Security.getProviders()} method.
363      *
364      * @param algorithm the name of the algorithm requested.
365      * See the Signature section in the <a href=
366      * "{@docRoot}/../specs/security/standard-names.html#signature-algorithms">
367      * Java Security Standard Algorithm Names Specification</a>
368      * for information about standard algorithm names.
369      *
370      * @param provider the name of the provider.
371      *
372      * @return the new {@code Signature} object
373      *
374      * @throws IllegalArgumentException if the provider name is {@code null}
375      *         or empty
376      *
377      * @throws NoSuchAlgorithmException if a {@code SignatureSpi}
378      *         implementation for the specified algorithm is not
379      *         available from the specified provider
380      *
381      * @throws NoSuchProviderException if the specified provider is not
382      *         registered in the security provider list
383      *
384      * @throws NullPointerException if {@code algorithm} is {@code null}
385      *
386      * @see Provider
387      */

388     public static Signature getInstance(String algorithm, String provider)
389             throws NoSuchAlgorithmException, NoSuchProviderException {
390         Objects.requireNonNull(algorithm, "null algorithm name");
391         if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
392             // exception compatibility with existing code
393             if (provider == null || provider.isEmpty()) {
394                 throw new IllegalArgumentException("missing provider");
395             }
396             Provider p = Security.getProvider(provider);
397             if (p == null) {
398                 throw new NoSuchProviderException
399                     ("no such provider: " + provider);
400             }
401             return getInstanceRSA(p);
402         }
403         Instance instance = GetInstance.getInstance
404                 ("Signature", SignatureSpi.class, algorithm, provider);
405         return getInstance(instance, algorithm);
406     }
407
408     /**
409      * Returns a Signature object that implements the specified
410      * signature algorithm.
411      *
412      * <p> A new Signature object encapsulating the
413      * SignatureSpi implementation from the specified Provider
414      * object is returned.  Note that the specified Provider object
415      * does not have to be registered in the provider list.
416      *
417      * @param algorithm the name of the algorithm requested.
418      * See the Signature section in the <a href=
419      * "{@docRoot}/../specs/security/standard-names.html#signature-algorithms">
420      * Java Security Standard Algorithm Names Specification</a>
421      * for information about standard algorithm names.
422      *
423      * @param provider the provider.
424      *
425      * @return the new {@code Signature} object
426      *
427      * @throws IllegalArgumentException if the provider is {@code null}
428      *
429      * @throws NoSuchAlgorithmException if a {@code SignatureSpi}
430      *         implementation for the specified algorithm is not available
431      *         from the specified {@code Provider} object
432      *
433      * @throws NullPointerException if {@code algorithm} is {@code null}
434      *
435      * @see Provider
436      *
437      * @since 1.4
438      */

439     public static Signature getInstance(String algorithm, Provider provider)
440             throws NoSuchAlgorithmException {
441         Objects.requireNonNull(algorithm, "null algorithm name");
442         if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
443             // exception compatibility with existing code
444             if (provider == null) {
445                 throw new IllegalArgumentException("missing provider");
446             }
447             return getInstanceRSA(provider);
448         }
449         Instance instance = GetInstance.getInstance
450                 ("Signature", SignatureSpi.class, algorithm, provider);
451         return getInstance(instance, algorithm);
452     }
453
454     // return an implementation for NONEwithRSA, which is a special case
455     // because of the Cipher.RSA/ECB/PKCS1Padding compatibility wrapper
456     private static Signature getInstanceRSA(Provider p)
457             throws NoSuchAlgorithmException {
458         // try Signature first
459         Service s = p.getService("Signature", RSA_SIGNATURE);
460         if (s != null) {
461             Instance instance = GetInstance.getInstance(s, SignatureSpi.class);
462             return getInstance(instance, RSA_SIGNATURE);
463         }
464         // check Cipher
465         try {
466             Cipher c = Cipher.getInstance(RSA_CIPHER, p);
467             return new Delegate(new CipherAdapter(c), RSA_SIGNATURE);
468         } catch (GeneralSecurityException e) {
469             // throw Signature style exception message to avoid confusion,
470             // but append Cipher exception as cause
471             throw new NoSuchAlgorithmException("no such algorithm: "
472                 + RSA_SIGNATURE + for provider " + p.getName(), e);
473         }
474     }
475
476     /**
477      * Returns the provider of this signature object.
478      *
479      * @return the provider of this signature object
480      */

481     public final Provider getProvider() {
482         chooseFirstProvider();
483         return this.provider;
484     }
485
486     private String getProviderName() {
487         return (provider == null)  ? "(no provider)" : provider.getName();
488     }
489
490     void chooseFirstProvider() {
491         // empty, overridden in Delegate
492     }
493
494     /**
495      * Initializes this object for verification. If this method is called
496      * again with a different argument, it negates the effect
497      * of this call.
498      *
499      * @param publicKey the public key of the identity whose signature is
500      * going to be verified.
501      *
502      * @exception InvalidKeyException if the key is invalid.
503      */

504     public final void initVerify(PublicKey publicKey)
505             throws InvalidKeyException {
506         engineInitVerify(publicKey);
507         state = VERIFY;
508
509         if (!skipDebug && pdebug != null) {
510             pdebug.println("Signature." + algorithm +
511                 " verification algorithm from: " + getProviderName());
512         }
513     }
514
515     /**
516      * Initialize this object for verification. If this method is called
517      * again with different arguments, it negates the effect
518      * of this call.
519      *
520      * @param publicKey the public key of the identity whose signature is
521      * going to be verified.
522      * @param params the parameters used for verifying this signature.
523      *
524      * @exception InvalidKeyException if the key is invalid.
525      * @exception InvalidAlgorithmParameterException if the params is invalid.
526      */

527     final void initVerify(PublicKey publicKey, AlgorithmParameterSpec params)
528             throws InvalidKeyException, InvalidAlgorithmParameterException {
529         engineInitVerify(publicKey, params);
530         state = VERIFY;
531
532         if (!skipDebug && pdebug != null) {
533             pdebug.println("Signature." + algorithm +
534                 " verification algorithm from: " + getProviderName());
535         }
536     }
537
538     private static PublicKey getPublicKeyFromCert(Certificate cert)
539             throws InvalidKeyException {
540         // If the certificate is of type X509Certificate,
541         // we should check whether it has a Key Usage
542         // extension marked as critical.
543         //if (cert instanceof java.security.cert.X509Certificate) {
544         if (cert instanceof X509Certificate) {
545             // Check whether the cert has a key usage extension
546             // marked as a critical extension.
547             // The OID for KeyUsage extension is 2.5.29.15.
548             X509Certificate c = (X509Certificate)cert;
549             Set<String> critSet = c.getCriticalExtensionOIDs();
550
551             if (critSet != null && !critSet.isEmpty()
552                 && critSet.contains("2.5.29.15")) {
553                 boolean[] keyUsageInfo = c.getKeyUsage();
554                 // keyUsageInfo[0] is for digitalSignature.
555                 if ((keyUsageInfo != null) && (keyUsageInfo[0] == false))
556                     throw new InvalidKeyException("Wrong key usage");
557             }
558         }
559         return cert.getPublicKey();
560     }
561
562     /**
563      * Initializes this object for verification, using the public key from
564      * the given certificate.
565      * <p>If the certificate is of type X.509 and has a <i>key usage</i>
566      * extension field marked as critical, and the value of the <i>key usage</i>
567      * extension field implies that the public key in
568      * the certificate and its corresponding private key are not
569      * supposed to be used for digital signatures, an
570      * {@code InvalidKeyException} is thrown.
571      *
572      * @param certificate the certificate of the identity whose signature is
573      * going to be verified.
574      *
575      * @exception InvalidKeyException  if the public key in the certificate
576      * is not encoded properly or does not include required  parameter
577      * information or cannot be used for digital signature purposes.
578      * @since 1.3
579      */

580     public final void initVerify(Certificate certificate)
581             throws InvalidKeyException {
582         engineInitVerify(getPublicKeyFromCert(certificate));
583         state = VERIFY;
584
585         if (!skipDebug && pdebug != null) {
586             pdebug.println("Signature." + algorithm +
587                 " verification algorithm from: " + getProviderName());
588         }
589     }
590
591     /**
592      * Initializes this object for verification, using the public key from
593      * the given certificate.
594      * <p>If the certificate is of type X.509 and has a <i>key usage</i>
595      * extension field marked as critical, and the value of the <i>key usage</i>
596      * extension field implies that the public key in
597      * the certificate and its corresponding private key are not
598      * supposed to be used for digital signatures, an
599      * {@code InvalidKeyException} is thrown.
600      *
601      * @param certificate the certificate of the identity whose signature is
602      * going to be verified.
603      * @param params the parameters used for verifying this signature.
604      *
605      * @exception InvalidKeyException  if the public key in the certificate
606      * is not encoded properly or does not include required  parameter
607      * information or cannot be used for digital signature purposes.
608      * @exception InvalidAlgorithmParameterException if the params is invalid.
609      *
610      * @since 13
611      */

612     final void initVerify(Certificate certificate,
613             AlgorithmParameterSpec params)
614             throws InvalidKeyException, InvalidAlgorithmParameterException {
615         engineInitVerify(getPublicKeyFromCert(certificate), params);
616         state = VERIFY;
617
618         if (!skipDebug && pdebug != null) {
619             pdebug.println("Signature." + algorithm +
620                 " verification algorithm from: " + getProviderName());
621         }
622     }
623
624     /**
625      * Initialize this object for signing. If this method is called
626      * again with a different argument, it negates the effect
627      * of this call.
628      *
629      * @param privateKey the private key of the identity whose signature
630      * is going to be generated.
631      *
632      * @exception InvalidKeyException if the key is invalid.
633      */

634     public final void initSign(PrivateKey privateKey)
635             throws InvalidKeyException {
636         engineInitSign(privateKey);
637         state = SIGN;
638
639         if (!skipDebug && pdebug != null) {
640             pdebug.println("Signature." + algorithm +
641                 " signing algorithm from: " + getProviderName());
642         }
643     }
644
645     /**
646      * Initialize this object for signing. If this method is called
647      * again with a different argument, it negates the effect
648      * of this call.
649      *
650      * @param privateKey the private key of the identity whose signature
651      * is going to be generated.
652      *
653      * @param random the source of randomness for this signature.
654      *
655      * @exception InvalidKeyException if the key is invalid.
656      */

657     public final void initSign(PrivateKey privateKey, SecureRandom random)
658             throws InvalidKeyException {
659         engineInitSign(privateKey, random);
660         state = SIGN;
661
662         if (!skipDebug && pdebug != null) {
663             pdebug.println("Signature." + algorithm +
664                 " signing algorithm from: " + getProviderName());
665         }
666     }
667
668     /**
669      * Initialize this object for signing. If this method is called
670      * again with different arguments, it negates the effect
671      * of this call.
672      *
673      * @param privateKey the private key of the identity whose signature
674      * is going to be generated.
675      * @param params the parameters used for generating signature.
676      * @param random the source of randomness for this signature.
677      *
678      * @exception InvalidKeyException if the key is invalid.
679      * @exception InvalidAlgorithmParameterException if the params is invalid
680      */

681     final void initSign(PrivateKey privateKey,
682             AlgorithmParameterSpec params, SecureRandom random)
683             throws InvalidKeyException, InvalidAlgorithmParameterException {
684         engineInitSign(privateKey, params, random);
685         state = SIGN;
686
687         if (!skipDebug && pdebug != null) {
688             pdebug.println("Signature." + algorithm +
689                 " signing algorithm from: " + getProviderName());
690         }
691     }
692
693     /**
694      * Returns the signature bytes of all the data updated.
695      * The format of the signature depends on the underlying
696      * signature scheme.
697      *
698      * <p>A call to this method resets this signature object to the state
699      * it was in when previously initialized for signing via a
700      * call to {@code initSign(PrivateKey)}. That is, the object is
701      * reset and available to generate another signature from the same
702      * signer, if desired, via new calls to {@code update} and
703      * {@code sign}.
704      *
705      * @return the signature bytes of the signing operation's result.
706      *
707      * @exception SignatureException if this signature object is not
708      * initialized properly or if this signature algorithm is unable to
709      * process the input data provided.
710      */

711     public final byte[] sign() throws SignatureException {
712         if (state == SIGN) {
713             return engineSign();
714         }
715         throw new SignatureException("object not initialized for " +
716                                      "signing");
717     }
718
719     /**
720      * Finishes the signature operation and stores the resulting signature
721      * bytes in the provided buffer {@code outbuf}, starting at
722      * {@code offset}.
723      * The format of the signature depends on the underlying
724      * signature scheme.
725      *
726      * <p>This signature object is reset to its initial state (the state it
727      * was in after a call to one of the {@code initSign} methods) and
728      * can be reused to generate further signatures with the same private key.
729      *
730      * @param outbuf buffer for the signature result.
731      *
732      * @param offset offset into {@code outbuf} where the signature is
733      * stored.
734      *
735      * @param len number of bytes within {@code outbuf} allotted for the
736      * signature.
737      *
738      * @return the number of bytes placed into {@code outbuf}.
739      *
740      * @exception SignatureException if this signature object is not
741      *     initialized properly, if this signature algorithm is unable to
742      *     process the input data provided, or if {@code len} is less
743      *     than the actual signature length.
744      * @exception IllegalArgumentException if {@code outbuf} is {@code null},
745      *     or {@code offset} or {@code len} is less than 0, or the sum of
746      *     {@code offset} and {@code len} is greater than the length of
747      *     {@code outbuf}.
748      *
749      * @since 1.2
750      */

751     public final int sign(byte[] outbuf, int offset, int len)
752         throws SignatureException {
753         if (outbuf == null) {
754             throw new IllegalArgumentException("No output buffer given");
755         }
756         if (offset < 0 || len < 0) {
757             throw new IllegalArgumentException("offset or len is less than 0");
758         }
759         if (outbuf.length - offset < len) {
760             throw new IllegalArgumentException
761                 ("Output buffer too small for specified offset and length");
762         }
763         if (state != SIGN) {
764             throw new SignatureException("object not initialized for " +
765                                          "signing");
766         }
767         return engineSign(outbuf, offset, len);
768     }
769
770     /**
771      * Verifies the passed-in signature.
772      *
773      * <p>A call to this method resets this signature object to the state
774      * it was in when previously initialized for verification via a
775      * call to {@code initVerify(PublicKey)}. That is, the object is
776      * reset and available to verify another signature from the identity
777      * whose public key was specified in the call to {@code initVerify}.
778      *
779      * @param signature the signature bytes to be verified.
780      *
781      * @return true if the signature was verified, false if not.
782      *
783      * @exception SignatureException if this signature object is not
784      * initialized properly, the passed-in signature is improperly
785      * encoded or of the wrong type, if this signature algorithm is unable to
786      * process the input data provided, etc.
787      */

788     public final boolean verify(byte[] signature) throws SignatureException {
789         if (state == VERIFY) {
790             return engineVerify(signature);
791         }
792         throw new SignatureException("object not initialized for " +
793                                      "verification");
794     }
795
796     /**
797      * Verifies the passed-in signature in the specified array
798      * of bytes, starting at the specified offset.
799      *
800      * <p>A call to this method resets this signature object to the state
801      * it was in when previously initialized for verification via a
802      * call to {@code initVerify(PublicKey)}. That is, the object is
803      * reset and available to verify another signature from the identity
804      * whose public key was specified in the call to {@code initVerify}.
805      *
806      *
807      * @param signature the signature bytes to be verified.
808      * @param offset the offset to start from in the array of bytes.
809      * @param length the number of bytes to use, starting at offset.
810      *
811      * @return true if the signature was verified, false if not.
812      *
813      * @exception SignatureException if this signature object is not
814      * initialized properly, the passed-in signature is improperly
815      * encoded or of the wrong type, if this signature algorithm is unable to
816      * process the input data provided, etc.
817      * @exception IllegalArgumentException if the {@code signature}
818      * byte array is {@code null}, or the {@code offset} or {@code length}
819      * is less than 0, or the sum of the {@code offset} and
820      * {@code length} is greater than the length of the
821      * {@code signature} byte array.
822      * @since 1.4
823      */

824     public final boolean verify(byte[] signature, int offset, int length)
825         throws SignatureException {
826         if (state == VERIFY) {
827             if (signature == null) {
828                 throw new IllegalArgumentException("signature is null");
829             }
830             if (offset < 0 || length < 0) {
831                 throw new IllegalArgumentException
832                     ("offset or length is less than 0");
833             }
834             if (signature.length - offset < length) {
835                 throw new IllegalArgumentException
836                     ("signature too small for specified offset and length");
837             }
838
839             return engineVerify(signature, offset, length);
840         }
841         throw new SignatureException("object not initialized for " +
842                                      "verification");
843     }
844
845     /**
846      * Updates the data to be signed or verified by a byte.
847      *
848      * @param b the byte to use for the update.
849      *
850      * @exception SignatureException if this signature object is not
851      * initialized properly.
852      */

853     public final void update(byte b) throws SignatureException {
854         if (state == VERIFY || state == SIGN) {
855             engineUpdate(b);
856         } else {
857             throw new SignatureException("object not initialized for "
858                                          + "signature or verification");
859         }
860     }
861
862     /**
863      * Updates the data to be signed or verified, using the specified
864      * array of bytes.
865      *
866      * @param data the byte array to use for the update.
867      *
868      * @exception SignatureException if this signature object is not
869      * initialized properly.
870      */

871     public final void update(byte[] data) throws SignatureException {
872         update(data, 0, data.length);
873     }
874
875     /**
876      * Updates the data to be signed or verified, using the specified
877      * array of bytes, starting at the specified offset.
878      *
879      * @param data the array of bytes.
880      * @param off the offset to start from in the array of bytes.
881      * @param len the number of bytes to use, starting at offset.
882      *
883      * @exception SignatureException if this signature object is not
884      *     initialized properly.
885      * @exception IllegalArgumentException if {@code data} is {@code null},
886      *     or {@code off} or {@code len} is less than 0, or the sum of
887      *     {@code off} and {@code len} is greater than the length of
888      *     {@code data}.
889      */

890     public final void update(byte[] data, int off, int len)
891             throws SignatureException {
892         if (state == SIGN || state == VERIFY) {
893             if (data == null) {
894                 throw new IllegalArgumentException("data is null");
895             }
896             if (off < 0 || len < 0) {
897                 throw new IllegalArgumentException("off or len is less than 0");
898             }
899             if (data.length - off < len) {
900                 throw new IllegalArgumentException
901                     ("data too small for specified offset and length");
902             }
903             engineUpdate(data, off, len);
904         } else {
905             throw new SignatureException("object not initialized for "
906                                          + "signature or verification");
907         }
908     }
909
910     /**
911      * Updates the data to be signed or verified using the specified
912      * ByteBuffer. Processes the {@code data.remaining()} bytes
913      * starting at {@code data.position()}.
914      * Upon return, the buffer's position will be equal to its limit;
915      * its limit will not have changed.
916      *
917      * @param data the ByteBuffer
918      *
919      * @exception SignatureException if this signature object is not
920      * initialized properly.
921      * @since 1.5
922      */

923     public final void update(ByteBuffer data) throws SignatureException {
924         if ((state != SIGN) && (state != VERIFY)) {
925             throw new SignatureException("object not initialized for "
926                                          + "signature or verification");
927         }
928         if (data == null) {
929             throw new NullPointerException();
930         }
931         engineUpdate(data);
932     }
933
934     /**
935      * Returns the name of the algorithm for this signature object.
936      *
937      * @return the name of the algorithm for this signature object.
938      */

939     public final String getAlgorithm() {
940         return this.algorithm;
941     }
942
943     /**
944      * Returns a string representation of this signature object,
945      * providing information that includes the state of the object
946      * and the name of the algorithm used.
947      *
948      * @return a string representation of this signature object.
949      */

950     public String toString() {
951         String initState = "";
952         switch (state) {
953         case UNINITIALIZED:
954             initState = "<not initialized>";
955             break;
956         case VERIFY:
957             initState = "<initialized for verifying>";
958             break;
959         case SIGN:
960             initState = "<initialized for signing>";
961             break;
962         }
963         return "Signature object: " + getAlgorithm() + initState;
964     }
965
966     /**
967      * Sets the specified algorithm parameter to the specified value.
968      * This method supplies a general-purpose mechanism through
969      * which it is possible to set the various parameters of this object.
970      * A parameter may be any settable parameter for the algorithm, such as
971      * a parameter size, or a source of random bits for signature generation
972      * (if appropriate), or an indication of whether or not to perform
973      * a specific but optional computation. A uniform algorithm-specific
974      * naming scheme for each parameter is desirable but left unspecified
975      * at this time.
976      *
977      * @param param the string identifier of the parameter.
978      * @param value the parameter value.
979      *
980      * @exception InvalidParameterException if {@code param} is an
981      * invalid parameter for this signature algorithm engine,
982      * the parameter is already set
983      * and cannot be set again, a security exception occurs, and so on.
984      *
985      * @see #getParameter
986      *
987      * @deprecated Use
988      * {@link #setParameter(java.security.spec.AlgorithmParameterSpec)
989      * setParameter}.
990      */

991     @Deprecated
992     public final void setParameter(String param, Object value)
993             throws InvalidParameterException {
994         engineSetParameter(param, value);
995     }
996
997     /**
998      * Initializes this signature engine with the specified parameter set.
999      *
1000      * @param params the parameters
1001      *
1002      * @exception InvalidAlgorithmParameterException if the given parameters
1003      * are inappropriate for this signature engine
1004      *
1005      * @see #getParameters
1006      */

1007     public final void setParameter(AlgorithmParameterSpec params)
1008             throws InvalidAlgorithmParameterException {
1009         engineSetParameter(params);
1010     }
1011
1012     /**
1013      * Returns the parameters used with this signature object.
1014      *
1015      * <p> If this signature has been previously initialized with parameters
1016      * (by calling the {@code setParameter} method), this method returns
1017      * the same parameters. If this signature has not been initialized with
1018      * parameters, this method may return a combination of default and
1019      * randomly generated parameter values if the underlying
1020      * signature implementation supports it and can successfully generate
1021      * them. Otherwise, {@code null} is returned.
1022      *
1023      * @return the parameters used with this signature, or {@code null}
1024      *
1025      * @see #setParameter(AlgorithmParameterSpec)
1026      * @since 1.4
1027      */

1028     public final AlgorithmParameters getParameters() {
1029         return engineGetParameters();
1030     }
1031
1032     /**
1033      * Gets the value of the specified algorithm parameter. This method
1034      * supplies a general-purpose mechanism through which it is possible to
1035      * get the various parameters of this object. A parameter may be any
1036      * settable parameter for the algorithm, such as a parameter size, or
1037      * a source of random bits for signature generation (if appropriate),
1038      * or an indication of whether or not to perform a specific but optional
1039      * computation. A uniform algorithm-specific naming scheme for each
1040      * parameter is desirable but left unspecified at this time.
1041      *
1042      * @param param the string name of the parameter.
1043      *
1044      * @return the object that represents the parameter value, or {@code nullif
1045      * there is none.
1046      *
1047      * @exception InvalidParameterException if {@code param} is an invalid
1048      * parameter for this engine, or another exception occurs while
1049      * trying to get this parameter.
1050      *
1051      * @see #setParameter(String, Object)
1052      *
1053      * @deprecated
1054      */

1055     @Deprecated
1056     public final Object getParameter(String param)
1057             throws InvalidParameterException {
1058         return engineGetParameter(param);
1059     }
1060
1061     /**
1062      * Returns a clone if the implementation is cloneable.
1063      *
1064      * @return a clone if the implementation is cloneable.
1065      *
1066      * @exception CloneNotSupportedException if this is called
1067      * on an implementation that does not support {@code Cloneable}.
1068      */

1069     public Object clone() throws CloneNotSupportedException {
1070         if (this instanceof Cloneable) {
1071             return super.clone();
1072         } else {
1073             throw new CloneNotSupportedException();
1074         }
1075     }
1076
1077     /*
1078      * The following class allows providers to extend from SignatureSpi
1079      * rather than from Signature. It represents a Signature with an
1080      * encapsulated, provider-supplied SPI object (of type SignatureSpi).
1081      * If the provider implementation is an instance of SignatureSpi, the
1082      * getInstance() methods above return an instance of this class, with
1083      * the SPI object encapsulated.
1084      *
1085      * Note: All SPI methods from the original Signature class have been
1086      * moved up the hierarchy into a new class (SignatureSpi), which has
1087      * been interposed in the hierarchy between the API (Signature)
1088      * and its original parent (Object).
1089      */

1090
1091     @SuppressWarnings("deprecation")
1092     private static class Delegate extends Signature {
1093
1094         // The provider implementation (delegate)
1095         // filled in once the provider is selected
1096         private SignatureSpi sigSpi;
1097
1098         // lock for mutex during provider selection
1099         private final Object lock;
1100
1101         // next service to try in provider selection
1102         // null once provider is selected
1103         private Service firstService;
1104
1105         // remaining services to try in provider selection
1106         // null once provider is selected
1107         private Iterator<Service> serviceIterator;
1108
1109         // constructor
1110         Delegate(SignatureSpi sigSpi, String algorithm) {
1111             super(algorithm);
1112             this.sigSpi = sigSpi;
1113             this.lock = null// no lock needed
1114         }
1115
1116         // used with delayed provider selection
1117         Delegate(Service service,
1118                         Iterator<Service> iterator, String algorithm) {
1119             super(algorithm);
1120             this.firstService = service;
1121             this.serviceIterator = iterator;
1122             this.lock = new Object();
1123         }
1124
1125         /**
1126          * Returns a clone if the delegate is cloneable.
1127          *
1128          * @return a clone if the delegate is cloneable.
1129          *
1130          * @exception CloneNotSupportedException if this is called on a
1131          * delegate that does not support {@code Cloneable}.
1132          */

1133         public Object clone() throws CloneNotSupportedException {
1134             chooseFirstProvider();
1135             if (sigSpi instanceof Cloneable) {
1136                 SignatureSpi sigSpiClone = (SignatureSpi)sigSpi.clone();
1137                 // Because 'algorithm' and 'provider' are private
1138                 // members of our supertype, we must perform a cast to
1139                 // access them.
1140                 Signature that =
1141                     new Delegate(sigSpiClone, ((Signature)this).algorithm);
1142                 that.provider = ((Signature)this).provider;
1143                 return that;
1144             } else {
1145                 throw new CloneNotSupportedException();
1146             }
1147         }
1148
1149         private static SignatureSpi newInstance(Service s)
1150                 throws NoSuchAlgorithmException {
1151             if (s.getType().equals("Cipher")) {
1152                 // must be NONEwithRSA
1153                 try {
1154                     Cipher c = Cipher.getInstance(RSA_CIPHER, s.getProvider());
1155                     return new CipherAdapter(c);
1156                 } catch (NoSuchPaddingException e) {
1157                     throw new NoSuchAlgorithmException(e);
1158                 }
1159             } else {
1160                 Object o = s.newInstance(null);
1161                 if (o instanceof SignatureSpi == false) {
1162                     throw new NoSuchAlgorithmException
1163                         ("Not a SignatureSpi: " + o.getClass().getName());
1164                 }
1165                 return (SignatureSpi)o;
1166             }
1167         }
1168
1169         // max number of debug warnings to print from chooseFirstProvider()
1170         private static int warnCount = 10;
1171
1172         /**
1173          * Choose the Spi from the first provider available. Used if
1174          * delayed provider selection is not possible because initSign()/
1175          * initVerify() is not the first method called.
1176          */

1177         void chooseFirstProvider() {
1178             if (sigSpi != null) {
1179                 return;
1180             }
1181             synchronized (lock) {
1182                 if (sigSpi != null) {
1183                     return;
1184                 }
1185                 if (debug != null) {
1186                     int w = --warnCount;
1187                     if (w >= 0) {
1188                         debug.println("Signature.init() not first method "
1189                             + "called, disabling delayed provider selection");
1190                         if (w == 0) {
1191                             debug.println("Further warnings of this type will "
1192                                 + "be suppressed");
1193                         }
1194                         new Exception("Debug call trace").printStackTrace();
1195                     }
1196                 }
1197                 Exception lastException = null;
1198                 while ((firstService != null) || serviceIterator.hasNext()) {
1199                     Service s;
1200                     if (firstService != null) {
1201                         s = firstService;
1202                         firstService = null;
1203                     } else {
1204                         s = serviceIterator.next();
1205                     }
1206                     if (isSpi(s) == false) {
1207                         continue;
1208                     }
1209                     try {
1210                         sigSpi = newInstance(s);
1211                         provider = s.getProvider();
1212                         // not needed any more
1213                         firstService = null;
1214                         serviceIterator = null;
1215                         return;
1216                     } catch (NoSuchAlgorithmException e) {
1217                         lastException = e;
1218                     }
1219                 }
1220                 ProviderException e = new ProviderException
1221                         ("Could not construct SignatureSpi instance");
1222                 if (lastException != null) {
1223                     e.initCause(lastException);
1224                 }
1225                 throw e;
1226             }
1227         }
1228
1229         // Used by engineSetParameter/engineInitSign/engineInitVerify() to
1230         // find the right provider with the supplied key, parameters, random source
1231         private void chooseProvider(int type, Key key,
1232                 AlgorithmParameterSpec params, SecureRandom random)
1233                 throws InvalidKeyException, InvalidAlgorithmParameterException {
1234             synchronized (lock) {
1235                 if (sigSpi != null) {
1236                     return;
1237                 }
1238                 Exception lastException = null;
1239                 while ((firstService != null) || serviceIterator.hasNext()) {
1240                     Service s;
1241                     if (firstService != null) {
1242                         s = firstService;
1243                         firstService = null;
1244                     } else {
1245                         s = serviceIterator.next();
1246                     }
1247                     // if provider says it does not support this key, ignore it
1248                     if (key != null && s.supportsParameter(key) == false) {
1249                         continue;
1250                     }
1251                     // if instance is not a SignatureSpi, ignore it
1252                     if (isSpi(s) == false) {
1253                         continue;
1254                     }
1255                     try {
1256                         SignatureSpi spi = newInstance(s);
1257                         tryOperation(spi, type, key, params, random);
1258                         provider = s.getProvider();
1259                         sigSpi = spi;
1260                         firstService = null;
1261                         serviceIterator = null;
1262                         return;
1263                     } catch (Exception e) {
1264                         // NoSuchAlgorithmException from newInstance()
1265                         // InvalidKeyException from init()
1266                         // RuntimeException (ProviderException) from init()
1267                         if (lastException == null) {
1268                             lastException = e;
1269                         }
1270                     }
1271                 }
1272                 // no working provider found, fail
1273                 if (lastException instanceof InvalidKeyException) {
1274                     throw (InvalidKeyException)lastException;
1275                 }
1276                 if (lastException instanceof RuntimeException) {
1277                     throw (RuntimeException)lastException;
1278                 }
1279                 if (lastException instanceof InvalidAlgorithmParameterException) {
1280                     throw (InvalidAlgorithmParameterException)lastException;
1281                 }
1282
1283                 String k = (key != null) ? key.getClass().getName() : "(null)";
1284                 throw new InvalidKeyException
1285                     ("No installed provider supports this key: "
1286                     + k, lastException);
1287             }
1288         }
1289
1290         private static final int I_PUB           = 1;
1291         private static final int I_PRIV          = 2;
1292         private static final int I_PRIV_SR       = 3;
1293         private static final int I_PUB_PARAM     = 4;
1294         private static final int I_PRIV_PARAM_SR = 5;
1295         private static final int S_PARAM         = 6;
1296
1297         private void tryOperation(SignatureSpi spi, int type, Key  key,
1298                 AlgorithmParameterSpec params, SecureRandom random)
1299                 throws InvalidKeyException, InvalidAlgorithmParameterException {
1300             switch (type) {
1301             case I_PUB:
1302                 spi.engineInitVerify((PublicKey)key);
1303                 break;
1304             case I_PUB_PARAM:
1305                 spi.engineInitVerify((PublicKey)key, params);
1306                 break;
1307             case I_PRIV:
1308                 spi.engineInitSign((PrivateKey)key);
1309                 break;
1310             case I_PRIV_SR:
1311                 spi.engineInitSign((PrivateKey)key, random);
1312                 break;
1313             case I_PRIV_PARAM_SR:
1314                 spi.engineInitSign((PrivateKey)key, params, random);
1315                 break;
1316             case S_PARAM:
1317                 spi.engineSetParameter(params);
1318                 break;
1319             default:
1320                 throw new AssertionError("Internal error: " + type);
1321             }
1322         }
1323
1324         protected void engineInitVerify(PublicKey publicKey)
1325                 throws InvalidKeyException {
1326             if (sigSpi != null) {
1327                 sigSpi.engineInitVerify(publicKey);
1328             } else {
1329                 try {
1330                     chooseProvider(I_PUB, publicKey, nullnull);
1331                 } catch (InvalidAlgorithmParameterException iape) {
1332                     // should not happen, re-throw as IKE just in case
1333                     throw new InvalidKeyException(iape);
1334                 }
1335             }
1336         }
1337
1338         void engineInitVerify(PublicKey publicKey,
1339                 AlgorithmParameterSpec params)
1340                 throws InvalidKeyException, InvalidAlgorithmParameterException {
1341             if (sigSpi != null) {
1342                 sigSpi.engineInitVerify(publicKey, params);
1343             } else {
1344                 chooseProvider(I_PUB_PARAM, publicKey, params, null);
1345             }
1346         }
1347
1348         protected void engineInitSign(PrivateKey privateKey)
1349                 throws InvalidKeyException {
1350             if (sigSpi != null) {
1351                 sigSpi.engineInitSign(privateKey);
1352             } else {
1353                 try {
1354                     chooseProvider(I_PRIV, privateKey, nullnull);
1355                 } catch (InvalidAlgorithmParameterException iape) {
1356                     // should not happen, re-throw as IKE just in case
1357                     throw new InvalidKeyException(iape);
1358                 }
1359             }
1360         }
1361
1362         protected void engineInitSign(PrivateKey privateKey, SecureRandom sr)
1363                 throws InvalidKeyException {
1364             if (sigSpi != null) {
1365                 sigSpi.engineInitSign(privateKey, sr);
1366             } else {
1367                 try {
1368                     chooseProvider(I_PRIV_SR, privateKey, null, sr);
1369                 } catch (InvalidAlgorithmParameterException iape) {
1370                     // should not happen, re-throw as IKE just in case
1371                     throw new InvalidKeyException(iape);
1372                 }
1373             }
1374         }
1375
1376         void engineInitSign(PrivateKey privateKey,
1377                 AlgorithmParameterSpec params, SecureRandom sr)
1378                 throws InvalidKeyException, InvalidAlgorithmParameterException {
1379             if (sigSpi != null) {
1380                 sigSpi.engineInitSign(privateKey, params, sr);
1381             } else {
1382                 chooseProvider(I_PRIV_PARAM_SR, privateKey, params, sr);
1383             }
1384         }
1385
1386         protected void engineUpdate(byte b) throws SignatureException {
1387             chooseFirstProvider();
1388             sigSpi.engineUpdate(b);
1389         }
1390
1391         protected void engineUpdate(byte[] b, int off, int len)
1392                 throws SignatureException {
1393             chooseFirstProvider();
1394             sigSpi.engineUpdate(b, off, len);
1395         }
1396
1397         protected void engineUpdate(ByteBuffer data) {
1398             chooseFirstProvider();
1399             sigSpi.engineUpdate(data);
1400         }
1401
1402         protected byte[] engineSign() throws SignatureException {
1403             chooseFirstProvider();
1404             return sigSpi.engineSign();
1405         }
1406
1407         protected int engineSign(byte[] outbuf, int offset, int len)
1408                 throws SignatureException {
1409             chooseFirstProvider();
1410             return sigSpi.engineSign(outbuf, offset, len);
1411         }
1412
1413         protected boolean engineVerify(byte[] sigBytes)
1414                 throws SignatureException {
1415             chooseFirstProvider();
1416             return sigSpi.engineVerify(sigBytes);
1417         }
1418
1419         protected boolean engineVerify(byte[] sigBytes, int offset, int length)
1420                 throws SignatureException {
1421             chooseFirstProvider();
1422             return sigSpi.engineVerify(sigBytes, offset, length);
1423         }
1424
1425         protected void engineSetParameter(String param, Object value)
1426                 throws InvalidParameterException {
1427             chooseFirstProvider();
1428             sigSpi.engineSetParameter(param, value);
1429         }
1430
1431         protected void engineSetParameter(AlgorithmParameterSpec params)
1432                 throws InvalidAlgorithmParameterException {
1433             if (sigSpi != null) {
1434                 sigSpi.engineSetParameter(params);
1435             } else {
1436                 try {
1437                     chooseProvider(S_PARAM, null, params, null);
1438                 } catch (InvalidKeyException ike) {
1439                     // should never happen, rethrow just in case
1440                     throw new InvalidAlgorithmParameterException(ike);
1441                 }
1442             }
1443         }
1444
1445         protected Object engineGetParameter(String param)
1446                 throws InvalidParameterException {
1447             chooseFirstProvider();
1448             return sigSpi.engineGetParameter(param);
1449         }
1450
1451         protected AlgorithmParameters engineGetParameters() {
1452             chooseFirstProvider();
1453             return sigSpi.engineGetParameters();
1454         }
1455     }
1456
1457     // adapter for RSA/ECB/PKCS1Padding ciphers
1458     @SuppressWarnings("deprecation")
1459     private static class CipherAdapter extends SignatureSpi {
1460
1461         private final Cipher cipher;
1462
1463         private ByteArrayOutputStream data;
1464
1465         CipherAdapter(Cipher cipher) {
1466             this.cipher = cipher;
1467         }
1468
1469         protected void engineInitVerify(PublicKey publicKey)
1470                 throws InvalidKeyException {
1471             cipher.init(Cipher.DECRYPT_MODE, publicKey);
1472             if (data == null) {
1473                 data = new ByteArrayOutputStream(128);
1474             } else {
1475                 data.reset();
1476             }
1477         }
1478
1479         protected void engineInitSign(PrivateKey privateKey)
1480                 throws InvalidKeyException {
1481             cipher.init(Cipher.ENCRYPT_MODE, privateKey);
1482             data = null;
1483         }
1484
1485         protected void engineInitSign(PrivateKey privateKey,
1486                 SecureRandom random) throws InvalidKeyException {
1487             cipher.init(Cipher.ENCRYPT_MODE, privateKey, random);
1488             data = null;
1489         }
1490
1491         protected void engineUpdate(byte b) throws SignatureException {
1492             engineUpdate(new byte[] {b}, 0, 1);
1493         }
1494
1495         protected void engineUpdate(byte[] b, int off, int len)
1496                 throws SignatureException {
1497             if (data != null) {
1498                 data.write(b, off, len);
1499                 return;
1500             }
1501             byte[] out = cipher.update(b, off, len);
1502             if ((out != null) && (out.length != 0)) {
1503                 throw new SignatureException
1504                     ("Cipher unexpectedly returned data");
1505             }
1506         }
1507
1508         protected byte[] engineSign() throws SignatureException {
1509             try {
1510                 return cipher.doFinal();
1511             } catch (IllegalBlockSizeException e) {
1512                 throw new SignatureException("doFinal() failed", e);
1513             } catch (BadPaddingException e) {
1514                 throw new SignatureException("doFinal() failed", e);
1515             }
1516         }
1517
1518         protected boolean engineVerify(byte[] sigBytes)
1519                 throws SignatureException {
1520             try {
1521                 byte[] out = cipher.doFinal(sigBytes);
1522                 byte[] dataBytes = data.toByteArray();
1523                 data.reset();
1524                 return MessageDigest.isEqual(out, dataBytes);
1525             } catch (BadPaddingException e) {
1526                 // e.g. wrong public key used
1527                 // return false rather than throwing exception
1528                 return false;
1529             } catch (IllegalBlockSizeException e) {
1530                 throw new SignatureException("doFinal() failed", e);
1531             }
1532         }
1533
1534         protected void engineSetParameter(String param, Object value)
1535                 throws InvalidParameterException {
1536             throw new InvalidParameterException("Parameters not supported");
1537         }
1538
1539         protected Object engineGetParameter(String param)
1540                 throws InvalidParameterException {
1541             throw new InvalidParameterException("Parameters not supported");
1542         }
1543
1544     }
1545
1546 }
1547