1 /*
2  * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
3  * Copyright (C) 2014 The Android Open Source Project
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.  Oracle designates this
9  * particular file as subject to the "Classpath" exception as provided
10  * by Oracle in the LICENSE file that accompanied this code.
11  *
12  * This code is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * version 2 for more details (a copy is included in the LICENSE file that
16  * accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License version
19  * 2 along with this work; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23  * or visit www.oracle.com if you need additional information or have any
24  * questions.
25  */
26 
27 package java.security;
28 
29 import java.security.spec.AlgorithmParameterSpec;
30 import java.util.*;
31 import java.util.concurrent.ConcurrentHashMap;
32 import java.io.*;
33 import java.security.cert.Certificate;
34 import java.security.cert.X509Certificate;
35 
36 import java.nio.ByteBuffer;
37 
38 import java.security.Provider.Service;
39 
40 import javax.crypto.Cipher;
41 import javax.crypto.CipherSpi;
42 import javax.crypto.IllegalBlockSizeException;
43 import javax.crypto.BadPaddingException;
44 import javax.crypto.NoSuchPaddingException;
45 import sun.security.jca.*;
46 import sun.security.jca.GetInstance.Instance;
47 
48 /**
49  * The Signature class is used to provide applications the functionality
50  * of a digital signature algorithm. Digital signatures are used for
51  * authentication and integrity assurance of digital data.
52  *
53  * <p> The signature algorithm can be, among others, the NIST standard
54  * DSA, using DSA and SHA-1. The DSA algorithm using the
55  * SHA-1 message digest algorithm can be specified as {@code SHA1withDSA}.
56  * In the case of RSA, there are multiple choices for the message digest
57  * algorithm, so the signing algorithm could be specified as, for example,
58  * {@code MD2withRSA}, {@code MD5withRSA}, or {@code SHA1withRSA}.
59  * The algorithm name must be specified, as there is no default.
60  *
61  * <p> A Signature object can be used to generate and verify digital
62  * signatures.
63  *
64  * <p> There are three phases to the use of a Signature object for
65  * either signing data or verifying a signature:<ol>
66  *
67  * <li>Initialization, with either
68  *
69  *     <ul>
70  *
71  *     <li>a public key, which initializes the signature for
72  *     verification (see {@link #initVerify(PublicKey) initVerify}), or
73  *
74  *     <li>a private key (and optionally a Secure Random Number Generator),
75  *     which initializes the signature for signing
76  *     (see {@link #initSign(PrivateKey)}
77  *     and {@link #initSign(PrivateKey, SecureRandom)}).
78  *
79  *     </ul>
80  *
81  * <li>Updating
82  *
83  * <p>Depending on the type of initialization, this will update the
84  * bytes to be signed or verified. See the
85  * {@link #update(byte) update} methods.
86  *
87  * <li>Signing or Verifying a signature on all updated bytes. See the
88  * {@link #sign() sign} methods and the {@link #verify(byte[]) verify}
89  * method.
90  *
91  * </ol>
92  *
93  * <p>Note that this class is abstract and extends from
94  * {@code SignatureSpi} for historical reasons.
95  * Application developers should only take notice of the methods defined in
96  * this {@code Signature} class; all the methods in
97  * the superclass are intended for cryptographic service providers who wish to
98  * supply their own implementations of digital signature algorithms.
99  *
100  * <p> Android provides the following {@code Signature} algorithms:
101  * <table>
102  *   <thead>
103  *     <tr>
104  *       <th>Algorithm</th>
105  *       <th>Supported API Levels</th>
106  *     </tr>
107  *   </thead>
108  *   <tbody>
109  *     <tr>
110  *       <td>DSA</td>
111  *       <td>1+</td>
112  *     </tr>
113  *     <tr>
114  *       <td>DSAwithSHA1</td>
115  *       <td>1+</td>
116  *     </tr>
117  *     <tr class="deprecated">
118  *       <td>DSS</td>
119  *       <td>1-19</td>
120  *     </tr>
121  *     <tr>
122  *       <td>ECDSA</td>
123  *       <td>11+</td>
124  *     </tr>
125  *     <tr>
126  *       <td>ECDSAwithSHA1</td>
127  *       <td>11+</td>
128  *     </tr>
129  *     <tr class="deprecated">
130  *       <td>MD2withRSA</td>
131  *       <td>1-3</td>
132  *     </tr>
133  *     <tr class="deprecated">
134  *       <td>MD4withRSA</td>
135  *       <td>1-8</td>
136  *     </tr>
137  *     <tr>
138  *       <td>MD5withRSA</td>
139  *       <td>1+</td>
140  *     </tr>
141  *     <tr class="deprecated">
142  *       <td>MD5withRSA/ISO9796-2</td>
143  *       <td>1-8</td>
144  *     </tr>
145  *     <tr>
146  *       <td>NONEwithDSA</td>
147  *       <td>1+</td>
148  *     </tr>
149  *     <tr>
150  *       <td>NONEwithECDSA</td>
151  *       <td>11+</td>
152  *     </tr>
153  *     <tr>
154  *       <td>NONEwithRSA</td>
155  *       <td>17+</td>
156  *     </tr>
157  *     <tr class="deprecated">
158  *       <td>RSASSA-PSS</td>
159  *       <td>1-8</td>
160  *     </tr>
161  *     <tr>
162  *       <td>SHA1withDSA</td>
163  *       <td>1+</td>
164  *     </tr>
165  *     <tr>
166  *       <td>SHA1withECDSA</td>
167  *       <td>11+</td>
168  *     </tr>
169  *     <tr>
170  *       <td>SHA1withRSA</td>
171  *       <td>1+</td>
172  *     </tr>
173  *     <tr class="deprecated">
174  *       <td>SHA1withRSA/ISO9796-2</td>
175  *       <td>1-8</td>
176  *     </tr>
177  *     <tr>
178  *       <td>SHA1withRSA/PSS</td>
179  *       <td>23+</td>
180  *     </tr>
181  *     <tr>
182  *       <td>SHA224withDSA</td>
183  *       <td>20+</td>
184  *     </tr>
185  *     <tr>
186  *       <td>SHA224withECDSA</td>
187  *       <td>20+</td>
188  *     </tr>
189  *     <tr>
190  *       <td>SHA224withRSA</td>
191  *       <td>20+</td>
192  *     </tr>
193  *     <tr>
194  *       <td>SHA224withRSA/PSS</td>
195  *       <td>23+</td>
196  *     </tr>
197  *     <tr>
198  *       <td>SHA256withDSA</td>
199  *       <td>1+</td>
200  *     </tr>
201  *     <tr>
202  *       <td>SHA256withECDSA</td>
203  *       <td>11+</td>
204  *     </tr>
205  *     <tr>
206  *       <td>SHA256withRSA</td>
207  *       <td>1+</td>
208  *     </tr>
209  *     <tr>
210  *       <td>SHA256withRSA/PSS</td>
211  *       <td>23+</td>
212  *     </tr>
213  *     <tr>
214  *       <td>SHA384withECDSA</td>
215  *       <td>11+</td>
216  *     </tr>
217  *     <tr>
218  *       <td>SHA384withRSA</td>
219  *       <td>1+</td>
220  *     </tr>
221  *     <tr>
222  *       <td>SHA384withRSA/PSS</td>
223  *       <td>23+</td>
224  *     </tr>
225  *     <tr>
226  *       <td>SHA512withECDSA</td>
227  *       <td>11+</td>
228  *     </tr>
229  *     <tr>
230  *       <td>SHA512withRSA</td>
231  *       <td>1+</td>
232  *     </tr>
233  *     <tr>
234  *       <td>SHA512withRSA/PSS</td>
235  *       <td>23+</td>
236  *     </tr>
237  *   </tbody>
238  * </table>
239  *
240  * These algorithms are described in the <a href=
241  * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Signature">
242  * Signature section</a> of the
243  * Java Cryptography Architecture Standard Algorithm Name Documentation.
244  *
245  * @author Benjamin Renaud
246  *
247  */
248 
249 public abstract class Signature extends SignatureSpi {
250 
251     // BEGIN Android-removed: this debugging mechanism is not supported in Android.
252     /*
253     private static final Debug debug =
254                         Debug.getInstance("jca", "Signature");
255 
256     private static final Debug pdebug =
257                         Debug.getInstance("provider", "Provider");
258     private static final boolean skipDebug =
259         Debug.isOn("engine=") && !Debug.isOn("signature");
260     // END Android-removed: this debugging mechanism is not supported in Android.
261     */
262 
263     /*
264      * The algorithm for this signature object.
265      * This value is used to map an OID to the particular algorithm.
266      * The mapping is done in AlgorithmObject.algOID(String algorithm)
267      */
268     private String algorithm;
269 
270     // The provider
271     Provider provider;
272 
273     /**
274      * Possible {@link #state} value, signifying that
275      * this signature object has not yet been initialized.
276      */
277     protected final static int UNINITIALIZED = 0;
278 
279     /**
280      * Possible {@link #state} value, signifying that
281      * this signature object has been initialized for signing.
282      */
283     protected final static int SIGN = 2;
284 
285     /**
286      * Possible {@link #state} value, signifying that
287      * this signature object has been initialized for verification.
288      */
289     protected final static int VERIFY = 3;
290 
291     /**
292      * Current state of this signature object.
293      */
294     protected int state = UNINITIALIZED;
295 
296     /**
297      * Creates a Signature object for the specified algorithm.
298      *
299      * @param algorithm the standard string name of the algorithm.
300      * See the Signature section in the <a href=
301      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Signature">
302      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
303      * for information about standard algorithm names.
304      */
Signature(String algorithm)305     protected Signature(String algorithm) {
306         this.algorithm = algorithm;
307     }
308 
309     // name of the special signature alg
310     private final static String RSA_SIGNATURE = "NONEwithRSA";
311 
312     // name of the equivalent cipher alg
313     private final static String RSA_CIPHER = "RSA/ECB/PKCS1Padding";
314 
315     // all the services we need to lookup for compatibility with Cipher
316     private final static List<ServiceId> rsaIds = Arrays.asList(
317         new ServiceId[] {
318             new ServiceId("Signature", "NONEwithRSA"),
319             new ServiceId("Cipher", "RSA/ECB/PKCS1Padding"),
320             new ServiceId("Cipher", "RSA/ECB"),
321             new ServiceId("Cipher", "RSA//PKCS1Padding"),
322             new ServiceId("Cipher", "RSA"),
323         }
324     );
325 
326     /**
327      * Returns a Signature object that implements the specified signature
328      * algorithm.
329      *
330      * <p> This method traverses the list of registered security Providers,
331      * starting with the most preferred Provider.
332      * A new Signature object encapsulating the
333      * SignatureSpi implementation from the first
334      * Provider that supports the specified algorithm is returned.
335      *
336      * <p> Note that the list of registered providers may be retrieved via
337      * the {@link Security#getProviders() Security.getProviders()} method.
338      *
339      * @param algorithm the standard name of the algorithm requested.
340      * See the Signature section in the <a href=
341      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Signature">
342      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
343      * for information about standard algorithm names.
344      *
345      * @return the new Signature object.
346      *
347      * @exception NoSuchAlgorithmException if no Provider supports a
348      *          Signature implementation for the
349      *          specified algorithm.
350      *
351      * @see Provider
352      */
getInstance(String algorithm)353     public static Signature getInstance(String algorithm)
354             throws NoSuchAlgorithmException {
355         List<Service> list;
356         if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
357             list = GetInstance.getServices(rsaIds);
358         } else {
359             list = GetInstance.getServices("Signature", algorithm);
360         }
361         Iterator<Service> t = list.iterator();
362         if (t.hasNext() == false) {
363             throw new NoSuchAlgorithmException
364                 (algorithm + " Signature not available");
365         }
366         // try services until we find an Spi or a working Signature subclass
367         NoSuchAlgorithmException failure;
368         do {
369             Service s = t.next();
370             if (isSpi(s)) {
371                 return new Delegate(algorithm);
372             } else {
373                 // must be a subclass of Signature, disable dynamic selection
374                 try {
375                     Instance instance =
376                         GetInstance.getInstance(s, SignatureSpi.class);
377                     return getInstance(instance, algorithm);
378                 } catch (NoSuchAlgorithmException e) {
379                     failure = e;
380                 }
381             }
382         } while (t.hasNext());
383         throw failure;
384     }
385 
getInstance(Instance instance, String algorithm)386     private static Signature getInstance(Instance instance, String algorithm) {
387         Signature sig;
388         if (instance.impl instanceof Signature) {
389             sig = (Signature)instance.impl;
390             sig.algorithm = algorithm;
391         } else {
392             SignatureSpi spi = (SignatureSpi)instance.impl;
393             sig = new Delegate(spi, algorithm);
394         }
395         sig.provider = instance.provider;
396         return sig;
397     }
398 
399     private final static Map<String,Boolean> signatureInfo;
400 
401     static {
402         signatureInfo = new ConcurrentHashMap<String,Boolean>();
403         Boolean TRUE = Boolean.TRUE;
404         // pre-initialize with values for our SignatureSpi implementations
405         signatureInfo.put("sun.security.provider.DSA$RawDSA", TRUE);
406         signatureInfo.put("sun.security.provider.DSA$SHA1withDSA", TRUE);
407         signatureInfo.put("sun.security.rsa.RSASignature$MD2withRSA", TRUE);
408         signatureInfo.put("sun.security.rsa.RSASignature$MD5withRSA", TRUE);
409         signatureInfo.put("sun.security.rsa.RSASignature$SHA1withRSA", TRUE);
410         signatureInfo.put("sun.security.rsa.RSASignature$SHA256withRSA", TRUE);
411         signatureInfo.put("sun.security.rsa.RSASignature$SHA384withRSA", TRUE);
412         signatureInfo.put("sun.security.rsa.RSASignature$SHA512withRSA", TRUE);
413         signatureInfo.put("com.sun.net.ssl.internal.ssl.RSASignature", TRUE);
414         signatureInfo.put("sun.security.pkcs11.P11Signature", TRUE);
415     }
416 
isSpi(Service s)417     private static boolean isSpi(Service s) {
418         if (s.getType().equals("Cipher")) {
419             // must be a CipherSpi, which we can wrap with the CipherAdapter
420             return true;
421         }
422         String className = s.getClassName();
423         Boolean result = signatureInfo.get(className);
424         if (result == null) {
425             try {
426                 Object instance = s.newInstance(null);
427                 // Signature extends SignatureSpi
428                 // so it is a "real" Spi if it is an
429                 // instance of SignatureSpi but not Signature
430                 boolean r = (instance instanceof SignatureSpi)
431                                 && (instance instanceof Signature == false);
432                 // BEGIN Android-removed: this debugging mechanism is not supported in Android.
433                 /*
434                 if ((debug != null) && (r == false)) {
435                     debug.println("Not a SignatureSpi " + className);
436                     debug.println("Delayed provider selection may not be "
437                         + "available for algorithm " + s.getAlgorithm());
438                 }
439                 */
440                 // END Android-removed: this debugging mechanism is not supported in Android.
441                 result = Boolean.valueOf(r);
442                 signatureInfo.put(className, result);
443             } catch (Exception e) {
444                 // something is wrong, assume not an SPI
445                 return false;
446             }
447         }
448         return result.booleanValue();
449     }
450 
451     /**
452      * Returns a Signature object that implements the specified signature
453      * algorithm.
454      *
455      * <p> A new Signature object encapsulating the
456      * SignatureSpi implementation from the specified provider
457      * is returned.  The specified provider must be registered
458      * in the security provider list.
459      *
460      * <p> Note that the list of registered providers may be retrieved via
461      * the {@link Security#getProviders() Security.getProviders()} method.
462      *
463      * @param algorithm the name of the algorithm requested.
464      * See the Signature section in the <a href=
465      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Signature">
466      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
467      * for information about standard algorithm names.
468      *
469      * @param provider the name of the provider.
470      *
471      * @return the new Signature object.
472      *
473      * @exception NoSuchAlgorithmException if a SignatureSpi
474      *          implementation for the specified algorithm is not
475      *          available from the specified provider.
476      *
477      * @exception NoSuchProviderException if the specified provider is not
478      *          registered in the security provider list.
479      *
480      * @exception IllegalArgumentException if the provider name is null
481      *          or empty.
482      *
483      * @see Provider
484      */
getInstance(String algorithm, String provider)485     public static Signature getInstance(String algorithm, String provider)
486             throws NoSuchAlgorithmException, NoSuchProviderException {
487         if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
488             // exception compatibility with existing code
489             if ((provider == null) || (provider.length() == 0)) {
490                 throw new IllegalArgumentException("missing provider");
491             }
492             Provider p = Security.getProvider(provider);
493             if (p == null) {
494                 throw new NoSuchProviderException
495                     ("no such provider: " + provider);
496             }
497             return getInstanceRSA(p);
498         }
499         Instance instance = GetInstance.getInstance
500                 ("Signature", SignatureSpi.class, algorithm, provider);
501         return getInstance(instance, algorithm);
502     }
503 
504     /**
505      * Returns a Signature object that implements the specified
506      * signature algorithm.
507      *
508      * <p> A new Signature object encapsulating the
509      * SignatureSpi implementation from the specified Provider
510      * object is returned.  Note that the specified Provider object
511      * does not have to be registered in the provider list.
512      *
513      * @param algorithm the name of the algorithm requested.
514      * See the Signature section in the <a href=
515      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Signature">
516      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
517      * for information about standard algorithm names.
518      *
519      * @param provider the provider.
520      *
521      * @return the new Signature object.
522      *
523      * @exception NoSuchAlgorithmException if a SignatureSpi
524      *          implementation for the specified algorithm is not available
525      *          from the specified Provider object.
526      *
527      * @exception IllegalArgumentException if the provider is null.
528      *
529      * @see Provider
530      *
531      * @since 1.4
532      */
getInstance(String algorithm, Provider provider)533     public static Signature getInstance(String algorithm, Provider provider)
534             throws NoSuchAlgorithmException {
535         if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
536             // exception compatibility with existing code
537             if (provider == null) {
538                 throw new IllegalArgumentException("missing provider");
539             }
540             return getInstanceRSA(provider);
541         }
542         Instance instance = GetInstance.getInstance
543                 ("Signature", SignatureSpi.class, algorithm, provider);
544         return getInstance(instance, algorithm);
545     }
546 
547     // return an implementation for NONEwithRSA, which is a special case
548     // because of the Cipher.RSA/ECB/PKCS1Padding compatibility wrapper
getInstanceRSA(Provider p)549     private static Signature getInstanceRSA(Provider p)
550             throws NoSuchAlgorithmException {
551         // try Signature first
552         Service s = p.getService("Signature", RSA_SIGNATURE);
553         if (s != null) {
554             Instance instance = GetInstance.getInstance(s, SignatureSpi.class);
555             return getInstance(instance, RSA_SIGNATURE);
556         }
557         // check Cipher
558         try {
559             Cipher c = Cipher.getInstance(RSA_CIPHER, p);
560             return new Delegate(new CipherAdapter(c), RSA_SIGNATURE);
561         } catch (GeneralSecurityException e) {
562             // throw Signature style exception message to avoid confusion,
563             // but append Cipher exception as cause
564             throw new NoSuchAlgorithmException("no such algorithm: "
565                 + RSA_SIGNATURE + " for provider " + p.getName(), e);
566         }
567     }
568 
569     /**
570      * Returns the provider of this signature object.
571      *
572      * @return the provider of this signature object
573      */
getProvider()574     public final Provider getProvider() {
575         chooseFirstProvider();
576         return this.provider;
577     }
578 
chooseFirstProvider()579     void chooseFirstProvider() {
580         // empty, overridden in Delegate
581     }
582 
583     /**
584      * Initializes this object for verification. If this method is called
585      * again with a different argument, it negates the effect
586      * of this call.
587      *
588      * @param publicKey the public key of the identity whose signature is
589      * going to be verified.
590      *
591      * @exception InvalidKeyException if the key is invalid.
592      */
initVerify(PublicKey publicKey)593     public final void initVerify(PublicKey publicKey)
594             throws InvalidKeyException {
595         engineInitVerify(publicKey);
596         state = VERIFY;
597 
598         // BEGIN Android-removed: this debugging mechanism is not supported in Android.
599         /*
600         if (!skipDebug && pdebug != null) {
601             pdebug.println("Signature." + algorithm +
602                 " verification algorithm from: " + this.provider.getName());
603         }
604         */
605         // END Android-removed: this debugging mechanism is not supported in Android.
606     }
607 
608     /**
609      * Initializes this object for verification, using the public key from
610      * the given certificate.
611      * <p>If the certificate is of type X.509 and has a <i>key usage</i>
612      * extension field marked as critical, and the value of the <i>key usage</i>
613      * extension field implies that the public key in
614      * the certificate and its corresponding private key are not
615      * supposed to be used for digital signatures, an
616      * {@code InvalidKeyException} is thrown.
617      *
618      * @param certificate the certificate of the identity whose signature is
619      * going to be verified.
620      *
621      * @exception InvalidKeyException  if the public key in the certificate
622      * is not encoded properly or does not include required  parameter
623      * information or cannot be used for digital signature purposes.
624      * @since 1.3
625      */
initVerify(Certificate certificate)626     public final void initVerify(Certificate certificate)
627             throws InvalidKeyException {
628         // If the certificate is of type X509Certificate,
629         // we should check whether it has a Key Usage
630         // extension marked as critical.
631         if (certificate instanceof java.security.cert.X509Certificate) {
632             // Check whether the cert has a key usage extension
633             // marked as a critical extension.
634             // The OID for KeyUsage extension is 2.5.29.15.
635             X509Certificate cert = (X509Certificate)certificate;
636             Set<String> critSet = cert.getCriticalExtensionOIDs();
637 
638             if (critSet != null && !critSet.isEmpty()
639                 && critSet.contains("2.5.29.15")) {
640                 boolean[] keyUsageInfo = cert.getKeyUsage();
641                 // keyUsageInfo[0] is for digitalSignature.
642                 if ((keyUsageInfo != null) && (keyUsageInfo[0] == false))
643                     throw new InvalidKeyException("Wrong key usage");
644             }
645         }
646 
647         PublicKey publicKey = certificate.getPublicKey();
648         engineInitVerify(publicKey);
649         state = VERIFY;
650 
651         // BEGIN Android-removed: this debugging mechanism is not supported in Android.
652         /*
653         if (!skipDebug && pdebug != null) {
654             pdebug.println("Signature." + algorithm +
655                 " verification algorithm from: " + this.provider.getName());
656         }
657         */
658         // END Android-removed: this debugging mechanism is not supported in Android.
659     }
660 
661     /**
662      * Initialize this object for signing. If this method is called
663      * again with a different argument, it negates the effect
664      * of this call.
665      *
666      * @param privateKey the private key of the identity whose signature
667      * is going to be generated.
668      *
669      * @exception InvalidKeyException if the key is invalid.
670      */
initSign(PrivateKey privateKey)671     public final void initSign(PrivateKey privateKey)
672             throws InvalidKeyException {
673         engineInitSign(privateKey);
674         state = SIGN;
675 
676         // BEGIN Android-removed: this debugging mechanism is not supported in Android.
677         /*
678         if (!skipDebug && pdebug != null) {
679             pdebug.println("Signature." + algorithm +
680                 " signing algorithm from: " + this.provider.getName());
681         }
682         */
683         // END Android-removed: this debugging mechanism is not supported in Android.
684     }
685 
686     /**
687      * Initialize this object for signing. If this method is called
688      * again with a different argument, it negates the effect
689      * of this call.
690      *
691      * @param privateKey the private key of the identity whose signature
692      * is going to be generated.
693      *
694      * @param random the source of randomness for this signature.
695      *
696      * @exception InvalidKeyException if the key is invalid.
697      */
initSign(PrivateKey privateKey, SecureRandom random)698     public final void initSign(PrivateKey privateKey, SecureRandom random)
699             throws InvalidKeyException {
700         engineInitSign(privateKey, random);
701         state = SIGN;
702 
703         // BEGIN Android-removed: this debugging mechanism is not supported in Android.
704         /*
705         if (!skipDebug && pdebug != null) {
706             pdebug.println("Signature." + algorithm +
707                 " signing algorithm from: " + this.provider.getName());
708         }
709         */
710         // END Android-removed: this debugging mechanism is not supported in Android.
711     }
712 
713     /**
714      * Returns the signature bytes of all the data updated.
715      * The format of the signature depends on the underlying
716      * signature scheme.
717      *
718      * <p>A call to this method resets this signature object to the state
719      * it was in when previously initialized for signing via a
720      * call to {@code initSign(PrivateKey)}. That is, the object is
721      * reset and available to generate another signature from the same
722      * signer, if desired, via new calls to {@code update} and
723      * {@code sign}.
724      *
725      * @return the signature bytes of the signing operation's result.
726      *
727      * @exception SignatureException if this signature object is not
728      * initialized properly or if this signature algorithm is unable to
729      * process the input data provided.
730      */
sign()731     public final byte[] sign() throws SignatureException {
732         if (state == SIGN) {
733             return engineSign();
734         }
735         throw new SignatureException("object not initialized for " +
736                                      "signing");
737     }
738 
739     /**
740      * Finishes the signature operation and stores the resulting signature
741      * bytes in the provided buffer {@code outbuf}, starting at
742      * {@code offset}.
743      * The format of the signature depends on the underlying
744      * signature scheme.
745      *
746      * <p>This signature object is reset to its initial state (the state it
747      * was in after a call to one of the {@code initSign} methods) and
748      * can be reused to generate further signatures with the same private key.
749      *
750      * @param outbuf buffer for the signature result.
751      *
752      * @param offset offset into {@code outbuf} where the signature is
753      * stored.
754      *
755      * @param len number of bytes within {@code outbuf} allotted for the
756      * signature.
757      *
758      * @return the number of bytes placed into {@code outbuf}.
759      *
760      * @exception SignatureException if this signature object is not
761      * initialized properly, if this signature algorithm is unable to
762      * process the input data provided, or if {@code len} is less
763      * than the actual signature length.
764      *
765      * @since 1.2
766      */
sign(byte[] outbuf, int offset, int len)767     public final int sign(byte[] outbuf, int offset, int len)
768         throws SignatureException {
769         if (outbuf == null) {
770             throw new IllegalArgumentException("No output buffer given");
771         }
772         if (offset < 0 || len < 0) {
773             throw new IllegalArgumentException("offset or len is less than 0");
774         }
775         if (outbuf.length - offset < len) {
776             throw new IllegalArgumentException
777                 ("Output buffer too small for specified offset and length");
778         }
779         if (state != SIGN) {
780             throw new SignatureException("object not initialized for " +
781                                          "signing");
782         }
783         return engineSign(outbuf, offset, len);
784     }
785 
786     /**
787      * Verifies the passed-in signature.
788      *
789      * <p>A call to this method resets this signature object to the state
790      * it was in when previously initialized for verification via a
791      * call to {@code initVerify(PublicKey)}. That is, the object is
792      * reset and available to verify another signature from the identity
793      * whose public key was specified in the call to {@code initVerify}.
794      *
795      * @param signature the signature bytes to be verified.
796      *
797      * @return true if the signature was verified, false if not.
798      *
799      * @exception SignatureException if this signature object is not
800      * initialized properly, the passed-in signature is improperly
801      * encoded or of the wrong type, if this signature algorithm is unable to
802      * process the input data provided, etc.
803      */
verify(byte[] signature)804     public final boolean verify(byte[] signature) throws SignatureException {
805         if (state == VERIFY) {
806             return engineVerify(signature);
807         }
808         throw new SignatureException("object not initialized for " +
809                                      "verification");
810     }
811 
812     /**
813      * Verifies the passed-in signature in the specified array
814      * of bytes, starting at the specified offset.
815      *
816      * <p>A call to this method resets this signature object to the state
817      * it was in when previously initialized for verification via a
818      * call to {@code initVerify(PublicKey)}. That is, the object is
819      * reset and available to verify another signature from the identity
820      * whose public key was specified in the call to {@code initVerify}.
821      *
822      *
823      * @param signature the signature bytes to be verified.
824      * @param offset the offset to start from in the array of bytes.
825      * @param length the number of bytes to use, starting at offset.
826      *
827      * @return true if the signature was verified, false if not.
828      *
829      * @exception SignatureException if this signature object is not
830      * initialized properly, the passed-in signature is improperly
831      * encoded or of the wrong type, if this signature algorithm is unable to
832      * process the input data provided, etc.
833      * @exception IllegalArgumentException if the {@code signature}
834      * byte array is null, or the {@code offset} or {@code length}
835      * is less than 0, or the sum of the {@code offset} and
836      * {@code length} is greater than the length of the
837      * {@code signature} byte array.
838      * @since 1.4
839      */
verify(byte[] signature, int offset, int length)840     public final boolean verify(byte[] signature, int offset, int length)
841         throws SignatureException {
842         if (state == VERIFY) {
843             if (signature == null) {
844                 throw new IllegalArgumentException("signature is null");
845             }
846             if (offset < 0 || length < 0) {
847                 throw new IllegalArgumentException
848                     ("offset or length is less than 0");
849             }
850             if (signature.length - offset < length) {
851                 throw new IllegalArgumentException
852                     ("signature too small for specified offset and length");
853             }
854 
855             return engineVerify(signature, offset, length);
856         }
857         throw new SignatureException("object not initialized for " +
858                                      "verification");
859     }
860 
861     /**
862      * Updates the data to be signed or verified by a byte.
863      *
864      * @param b the byte to use for the update.
865      *
866      * @exception SignatureException if this signature object is not
867      * initialized properly.
868      */
update(byte b)869     public final void update(byte b) throws SignatureException {
870         if (state == VERIFY || state == SIGN) {
871             engineUpdate(b);
872         } else {
873             throw new SignatureException("object not initialized for "
874                                          + "signature or verification");
875         }
876     }
877 
878     /**
879      * Updates the data to be signed or verified, using the specified
880      * array of bytes.
881      *
882      * @param data the byte array to use for the update.
883      *
884      * @exception SignatureException if this signature object is not
885      * initialized properly.
886      */
update(byte[] data)887     public final void update(byte[] data) throws SignatureException {
888         update(data, 0, data.length);
889     }
890 
891     /**
892      * Updates the data to be signed or verified, using the specified
893      * array of bytes, starting at the specified offset.
894      *
895      * @param data the array of bytes.
896      * @param off the offset to start from in the array of bytes.
897      * @param len the number of bytes to use, starting at offset.
898      *
899      * @exception SignatureException if this signature object is not
900      * initialized properly.
901      */
update(byte[] data, int off, int len)902     public final void update(byte[] data, int off, int len)
903             throws SignatureException {
904         if (state == SIGN || state == VERIFY) {
905             if (data == null) {
906                 throw new IllegalArgumentException("data is null");
907             }
908             if (off < 0 || len < 0) {
909                 throw new IllegalArgumentException("off or len is less than 0");
910             }
911             if (data.length - off < len) {
912                 throw new IllegalArgumentException
913                     ("data too small for specified offset and length");
914             }
915             engineUpdate(data, off, len);
916         } else {
917             throw new SignatureException("object not initialized for "
918                                          + "signature or verification");
919         }
920     }
921 
922     /**
923      * Updates the data to be signed or verified using the specified
924      * ByteBuffer. Processes the {@code data.remaining()} bytes
925      * starting at at {@code data.position()}.
926      * Upon return, the buffer's position will be equal to its limit;
927      * its limit will not have changed.
928      *
929      * @param data the ByteBuffer
930      *
931      * @exception SignatureException if this signature object is not
932      * initialized properly.
933      * @since 1.5
934      */
update(ByteBuffer data)935     public final void update(ByteBuffer data) throws SignatureException {
936         if ((state != SIGN) && (state != VERIFY)) {
937             throw new SignatureException("object not initialized for "
938                                          + "signature or verification");
939         }
940         if (data == null) {
941             throw new NullPointerException();
942         }
943         engineUpdate(data);
944     }
945 
946     /**
947      * Returns the name of the algorithm for this signature object.
948      *
949      * @return the name of the algorithm for this signature object.
950      */
getAlgorithm()951     public final String getAlgorithm() {
952         return this.algorithm;
953     }
954 
955     /**
956      * Returns a string representation of this signature object,
957      * providing information that includes the state of the object
958      * and the name of the algorithm used.
959      *
960      * @return a string representation of this signature object.
961      */
toString()962     public String toString() {
963         String initState = "";
964         switch (state) {
965         case UNINITIALIZED:
966             initState = "<not initialized>";
967             break;
968         case VERIFY:
969             initState = "<initialized for verifying>";
970             break;
971         case SIGN:
972             initState = "<initialized for signing>";
973             break;
974         }
975         return "Signature object: " + getAlgorithm() + initState;
976     }
977 
978     /**
979      * Sets the specified algorithm parameter to the specified value.
980      * This method supplies a general-purpose mechanism through
981      * which it is possible to set the various parameters of this object.
982      * A parameter may be any settable parameter for the algorithm, such as
983      * a parameter size, or a source of random bits for signature generation
984      * (if appropriate), or an indication of whether or not to perform
985      * a specific but optional computation. A uniform algorithm-specific
986      * naming scheme for each parameter is desirable but left unspecified
987      * at this time.
988      *
989      * @param param the string identifier of the parameter.
990      * @param value the parameter value.
991      *
992      * @exception InvalidParameterException if {@code param} is an
993      * invalid parameter for this signature algorithm engine,
994      * the parameter is already set
995      * and cannot be set again, a security exception occurs, and so on.
996      *
997      * @see #getParameter
998      *
999      * @deprecated Use
1000      * {@link #setParameter(java.security.spec.AlgorithmParameterSpec)
1001      * setParameter}.
1002      */
1003     @Deprecated
setParameter(String param, Object value)1004     public final void setParameter(String param, Object value)
1005             throws InvalidParameterException {
1006         engineSetParameter(param, value);
1007     }
1008 
1009     /**
1010      * Initializes this signature engine with the specified parameter set.
1011      *
1012      * @param params the parameters
1013      *
1014      * @exception InvalidAlgorithmParameterException if the given parameters
1015      * are inappropriate for this signature engine
1016      *
1017      * @see #getParameters
1018      */
setParameter(AlgorithmParameterSpec params)1019     public final void setParameter(AlgorithmParameterSpec params)
1020             throws InvalidAlgorithmParameterException {
1021         engineSetParameter(params);
1022     }
1023 
1024     /**
1025      * Returns the parameters used with this signature object.
1026      *
1027      * <p>The returned parameters may be the same that were used to initialize
1028      * this signature, or may contain a combination of default and randomly
1029      * generated parameter values used by the underlying signature
1030      * implementation if this signature requires algorithm parameters but
1031      * was not initialized with any.
1032      *
1033      * @return the parameters used with this signature, or null if this
1034      * signature does not use any parameters.
1035      *
1036      * @see #setParameter(AlgorithmParameterSpec)
1037      * @since 1.4
1038      */
getParameters()1039     public final AlgorithmParameters getParameters() {
1040         return engineGetParameters();
1041     }
1042 
1043     /**
1044      * Gets the value of the specified algorithm parameter. This method
1045      * supplies a general-purpose mechanism through which it is possible to
1046      * get the various parameters of this object. A parameter may be any
1047      * settable parameter for the algorithm, such as a parameter size, or
1048      * a source of random bits for signature generation (if appropriate),
1049      * or an indication of whether or not to perform a specific but optional
1050      * computation. A uniform algorithm-specific naming scheme for each
1051      * parameter is desirable but left unspecified at this time.
1052      *
1053      * @param param the string name of the parameter.
1054      *
1055      * @return the object that represents the parameter value, or null if
1056      * there is none.
1057      *
1058      * @exception InvalidParameterException if {@code param} is an invalid
1059      * parameter for this engine, or another exception occurs while
1060      * trying to get this parameter.
1061      *
1062      * @see #setParameter(String, Object)
1063      *
1064      * @deprecated Deprecated.
1065      */
1066     @Deprecated
1067     // Android-changed add "Deprecated."
getParameter(String param)1068     public final Object getParameter(String param)
1069             throws InvalidParameterException {
1070         return engineGetParameter(param);
1071     }
1072 
1073     /**
1074      * Returns a clone if the implementation is cloneable.
1075      *
1076      * @return a clone if the implementation is cloneable.
1077      *
1078      * @exception CloneNotSupportedException if this is called
1079      * on an implementation that does not support {@code Cloneable}.
1080      */
clone()1081     public Object clone() throws CloneNotSupportedException {
1082         if (this instanceof Cloneable) {
1083             return super.clone();
1084         } else {
1085             throw new CloneNotSupportedException();
1086         }
1087     }
1088 
1089     /**
1090      * Returns the {@code SignatureSpi} backing this {@code Signature}.
1091      *
1092      * @hide
1093      */
getCurrentSpi()1094     public SignatureSpi getCurrentSpi() {
1095       return null;
1096     }
1097 
1098     /*
1099      * The following class allows providers to extend from SignatureSpi
1100      * rather than from Signature. It represents a Signature with an
1101      * encapsulated, provider-supplied SPI object (of type SignatureSpi).
1102      * If the provider implementation is an instance of SignatureSpi, the
1103      * getInstance() methods above return an instance of this class, with
1104      * the SPI object encapsulated.
1105      *
1106      * Note: All SPI methods from the original Signature class have been
1107      * moved up the hierarchy into a new class (SignatureSpi), which has
1108      * been interposed in the hierarchy between the API (Signature)
1109      * and its original parent (Object).
1110      */
1111 
1112     @SuppressWarnings("deprecation")
1113     private static class Delegate extends Signature {
1114 
1115         // The provider implementation (delegate)
1116         // filled in once the provider is selected
1117         // BEGIN Android-added
1118         // (Not necessarily Android specific)
1119         // Invariant to be preserved: sigSpi cannot be changed once it was assigned to something
1120         // different than null and lock is null. That is the case when sigSpi is specified in the
1121         // constructor.
1122         // END Android-added
1123         private SignatureSpi sigSpi;
1124 
1125         // lock for mutex during provider selection
1126         private final Object lock;
1127 
1128         // constructor
Delegate(SignatureSpi sigSpi, String algorithm)1129         Delegate(SignatureSpi sigSpi, String algorithm) {
1130             super(algorithm);
1131             this.sigSpi = sigSpi;
1132             this.lock = null;
1133         }
1134 
1135         // used with delayed provider selection
Delegate(String algorithm)1136         Delegate(String algorithm) {
1137             super(algorithm);
1138             this.lock = new Object();
1139         }
1140 
1141         /**
1142          * Returns a clone if the delegate is cloneable.
1143          *
1144          * @return a clone if the delegate is cloneable.
1145          *
1146          * @exception CloneNotSupportedException if this is called on a
1147          * delegate that does not support {@code Cloneable}.
1148          */
clone()1149         public Object clone() throws CloneNotSupportedException {
1150             chooseFirstProvider();
1151             if (sigSpi instanceof Cloneable) {
1152                 SignatureSpi sigSpiClone = (SignatureSpi)sigSpi.clone();
1153                 // Because 'algorithm' and 'provider' are private
1154                 // members of our supertype, we must perform a cast to
1155                 // access them.
1156                 Signature that =
1157                     new Delegate(sigSpiClone, ((Signature)this).algorithm);
1158                 that.provider = ((Signature)this).provider;
1159                 return that;
1160             } else {
1161                 throw new CloneNotSupportedException();
1162             }
1163         }
1164 
newInstance(Service s)1165         private static SignatureSpi newInstance(Service s)
1166                 throws NoSuchAlgorithmException {
1167             if (s.getType().equals("Cipher")) {
1168                 // must be NONEwithRSA
1169                 try {
1170                     Cipher c = Cipher.getInstance(RSA_CIPHER, s.getProvider());
1171                     return new CipherAdapter(c);
1172                 } catch (NoSuchPaddingException e) {
1173                     throw new NoSuchAlgorithmException(e);
1174                 }
1175             } else {
1176                 Object o = s.newInstance(null);
1177                 if (o instanceof SignatureSpi == false) {
1178                     throw new NoSuchAlgorithmException
1179                         ("Not a SignatureSpi: " + o.getClass().getName());
1180                 }
1181                 return (SignatureSpi)o;
1182             }
1183         }
1184 
1185         // max number of debug warnings to print from chooseFirstProvider()
1186         private static int warnCount = 10;
1187 
1188         /**
1189          * Choose the Spi from the first provider available. Used if
1190          * delayed provider selection is not possible because initSign()/
1191          * initVerify() is not the first method called.
1192          */
chooseFirstProvider()1193         void chooseFirstProvider() {
1194             if (sigSpi != null) {
1195                 return;
1196             }
1197             synchronized (lock) {
1198                 if (sigSpi != null) {
1199                     return;
1200                 }
1201                 // BEGIN Android-removed: this debugging mechanism is not supported in Android.
1202                 /*
1203                 if (debug != null) {
1204                     int w = --warnCount;
1205                     if (w >= 0) {
1206                         debug.println("Signature.init() not first method "
1207                             + "called, disabling delayed provider selection");
1208                         if (w == 0) {
1209                             debug.println("Further warnings of this type will "
1210                                 + "be suppressed");
1211                         }
1212                         new Exception("Call trace").printStackTrace();
1213                     }
1214                 }
1215                 */
1216                 // END Android-removed: this debugging mechanism is not supported in Android.
1217                 Exception lastException = null;
1218                 List<Service> list;
1219                 if (((Signature)this).algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
1220                     list = GetInstance.getServices(rsaIds);
1221                 } else {
1222                     list = GetInstance.getServices("Signature",
1223                             ((Signature)this).algorithm);
1224                 }
1225                 for (Service s : list) {
1226                     if (isSpi(s) == false) {
1227                         continue;
1228                     }
1229                     try {
1230                         sigSpi = newInstance(s);
1231                         provider = s.getProvider();
1232                         return;
1233                     } catch (NoSuchAlgorithmException e) {
1234                         lastException = e;
1235                     }
1236                 }
1237                 ProviderException e = new ProviderException
1238                         ("Could not construct SignatureSpi instance");
1239                 if (lastException != null) {
1240                     e.initCause(lastException);
1241                 }
1242                 throw e;
1243             }
1244         }
1245 
chooseProvider(int type, Key key, SecureRandom random)1246         private void chooseProvider(int type, Key key, SecureRandom random)
1247                 throws InvalidKeyException {
1248             synchronized (lock) {
1249                 if (sigSpi != null && key == null) {
1250                     init(sigSpi, type, key, random);
1251                     return;
1252                 }
1253                 Exception lastException = null;
1254                 List<Service> list;
1255                 if (((Signature)this).algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
1256                     list = GetInstance.getServices(rsaIds);
1257                 } else {
1258                     list = GetInstance.getServices("Signature",
1259                             ((Signature)this).algorithm);
1260                 }
1261                 for (Service s : list) {
1262                     // if provider says it does not support this key, ignore it
1263                     if (s.supportsParameter(key) == false) {
1264                         continue;
1265                     }
1266                     // if instance is not a SignatureSpi, ignore it
1267                     if (isSpi(s) == false) {
1268                         continue;
1269                     }
1270                     try {
1271                         SignatureSpi spi = newInstance(s);
1272                         init(spi, type, key, random);
1273                         provider = s.getProvider();
1274                         sigSpi = spi;
1275                         return;
1276                     } catch (Exception e) {
1277                         // NoSuchAlgorithmException from newInstance()
1278                         // InvalidKeyException from init()
1279                         // RuntimeException (ProviderException) from init()
1280                         if (lastException == null) {
1281                             lastException = e;
1282                         }
1283                         if (lastException instanceof InvalidKeyException) {
1284                           throw (InvalidKeyException)lastException;
1285                         }
1286                     }
1287                 }
1288                 // no working provider found, fail
1289                 if (lastException instanceof InvalidKeyException) {
1290                     throw (InvalidKeyException)lastException;
1291                 }
1292                 if (lastException instanceof RuntimeException) {
1293                     throw (RuntimeException)lastException;
1294                 }
1295                 String k = (key != null) ? key.getClass().getName() : "(null)";
1296                 throw new InvalidKeyException
1297                     ("No installed provider supports this key: "
1298                     + k, lastException);
1299             }
1300         }
1301 
1302         private final static int I_PUB     = 1;
1303         private final static int I_PRIV    = 2;
1304         private final static int I_PRIV_SR = 3;
1305 
init(SignatureSpi spi, int type, Key key, SecureRandom random)1306         private void init(SignatureSpi spi, int type, Key  key,
1307                 SecureRandom random) throws InvalidKeyException {
1308             switch (type) {
1309             case I_PUB:
1310                 spi.engineInitVerify((PublicKey)key);
1311                 break;
1312             case I_PRIV:
1313                 spi.engineInitSign((PrivateKey)key);
1314                 break;
1315             case I_PRIV_SR:
1316                 spi.engineInitSign((PrivateKey)key, random);
1317                 break;
1318             default:
1319                 throw new AssertionError("Internal error: " + type);
1320             }
1321         }
1322 
engineInitVerify(PublicKey publicKey)1323         protected void engineInitVerify(PublicKey publicKey)
1324                 throws InvalidKeyException {
1325             if (sigSpi != null && (lock == null || publicKey == null)) {
1326                 sigSpi.engineInitVerify(publicKey);
1327             } else {
1328                 chooseProvider(I_PUB, publicKey, null);
1329             }
1330         }
1331 
engineInitSign(PrivateKey privateKey)1332         protected void engineInitSign(PrivateKey privateKey)
1333                 throws InvalidKeyException {
1334             if (sigSpi != null && (lock == null || privateKey == null)) {
1335                 sigSpi.engineInitSign(privateKey);
1336             } else {
1337                 chooseProvider(I_PRIV, privateKey, null);
1338             }
1339         }
1340 
engineInitSign(PrivateKey privateKey, SecureRandom sr)1341         protected void engineInitSign(PrivateKey privateKey, SecureRandom sr)
1342                 throws InvalidKeyException {
1343             if (sigSpi != null  && (lock == null || privateKey == null)) {
1344                 sigSpi.engineInitSign(privateKey, sr);
1345             } else {
1346                 chooseProvider(I_PRIV_SR, privateKey, sr);
1347             }
1348         }
1349 
engineUpdate(byte b)1350         protected void engineUpdate(byte b) throws SignatureException {
1351             chooseFirstProvider();
1352             sigSpi.engineUpdate(b);
1353         }
1354 
engineUpdate(byte[] b, int off, int len)1355         protected void engineUpdate(byte[] b, int off, int len)
1356                 throws SignatureException {
1357             chooseFirstProvider();
1358             sigSpi.engineUpdate(b, off, len);
1359         }
1360 
engineUpdate(ByteBuffer data)1361         protected void engineUpdate(ByteBuffer data) {
1362             chooseFirstProvider();
1363             sigSpi.engineUpdate(data);
1364         }
1365 
engineSign()1366         protected byte[] engineSign() throws SignatureException {
1367             chooseFirstProvider();
1368             return sigSpi.engineSign();
1369         }
1370 
engineSign(byte[] outbuf, int offset, int len)1371         protected int engineSign(byte[] outbuf, int offset, int len)
1372                 throws SignatureException {
1373             chooseFirstProvider();
1374             return sigSpi.engineSign(outbuf, offset, len);
1375         }
1376 
engineVerify(byte[] sigBytes)1377         protected boolean engineVerify(byte[] sigBytes)
1378                 throws SignatureException {
1379             chooseFirstProvider();
1380             return sigSpi.engineVerify(sigBytes);
1381         }
1382 
engineVerify(byte[] sigBytes, int offset, int length)1383         protected boolean engineVerify(byte[] sigBytes, int offset, int length)
1384                 throws SignatureException {
1385             chooseFirstProvider();
1386             return sigSpi.engineVerify(sigBytes, offset, length);
1387         }
1388 
engineSetParameter(String param, Object value)1389         protected void engineSetParameter(String param, Object value)
1390                 throws InvalidParameterException {
1391             chooseFirstProvider();
1392             sigSpi.engineSetParameter(param, value);
1393         }
1394 
engineSetParameter(AlgorithmParameterSpec params)1395         protected void engineSetParameter(AlgorithmParameterSpec params)
1396                 throws InvalidAlgorithmParameterException {
1397             chooseFirstProvider();
1398             sigSpi.engineSetParameter(params);
1399         }
1400 
engineGetParameter(String param)1401         protected Object engineGetParameter(String param)
1402                 throws InvalidParameterException {
1403             chooseFirstProvider();
1404             return sigSpi.engineGetParameter(param);
1405         }
1406 
engineGetParameters()1407         protected AlgorithmParameters engineGetParameters() {
1408             chooseFirstProvider();
1409             return sigSpi.engineGetParameters();
1410         }
1411 
1412         @Override
getCurrentSpi()1413         public SignatureSpi getCurrentSpi() {
1414             if (lock == null) {
1415                 return sigSpi;
1416             }
1417             synchronized (lock) {
1418                 return sigSpi;
1419             }
1420         }
1421     }
1422 
1423     // adapter for RSA/ECB/PKCS1Padding ciphers
1424     @SuppressWarnings("deprecation")
1425     private static class CipherAdapter extends SignatureSpi {
1426 
1427         private final Cipher cipher;
1428 
1429         private ByteArrayOutputStream data;
1430 
CipherAdapter(Cipher cipher)1431         CipherAdapter(Cipher cipher) {
1432             this.cipher = cipher;
1433         }
1434 
engineInitVerify(PublicKey publicKey)1435         protected void engineInitVerify(PublicKey publicKey)
1436                 throws InvalidKeyException {
1437             cipher.init(Cipher.DECRYPT_MODE, publicKey);
1438             if (data == null) {
1439                 data = new ByteArrayOutputStream(128);
1440             } else {
1441                 data.reset();
1442             }
1443         }
1444 
engineInitSign(PrivateKey privateKey)1445         protected void engineInitSign(PrivateKey privateKey)
1446                 throws InvalidKeyException {
1447             cipher.init(Cipher.ENCRYPT_MODE, privateKey);
1448             data = null;
1449         }
1450 
engineInitSign(PrivateKey privateKey, SecureRandom random)1451         protected void engineInitSign(PrivateKey privateKey,
1452                 SecureRandom random) throws InvalidKeyException {
1453             cipher.init(Cipher.ENCRYPT_MODE, privateKey, random);
1454             data = null;
1455         }
1456 
engineUpdate(byte b)1457         protected void engineUpdate(byte b) throws SignatureException {
1458             engineUpdate(new byte[] {b}, 0, 1);
1459         }
1460 
engineUpdate(byte[] b, int off, int len)1461         protected void engineUpdate(byte[] b, int off, int len)
1462                 throws SignatureException {
1463             if (data != null) {
1464                 data.write(b, off, len);
1465                 return;
1466             }
1467             byte[] out = cipher.update(b, off, len);
1468             if ((out != null) && (out.length != 0)) {
1469                 throw new SignatureException
1470                     ("Cipher unexpectedly returned data");
1471             }
1472         }
1473 
engineSign()1474         protected byte[] engineSign() throws SignatureException {
1475             try {
1476                 return cipher.doFinal();
1477             } catch (IllegalBlockSizeException e) {
1478                 throw new SignatureException("doFinal() failed", e);
1479             } catch (BadPaddingException e) {
1480                 throw new SignatureException("doFinal() failed", e);
1481             }
1482         }
1483 
engineVerify(byte[] sigBytes)1484         protected boolean engineVerify(byte[] sigBytes)
1485                 throws SignatureException {
1486             try {
1487                 byte[] out = cipher.doFinal(sigBytes);
1488                 byte[] dataBytes = data.toByteArray();
1489                 data.reset();
1490                 return MessageDigest.isEqual(out, dataBytes);
1491             } catch (BadPaddingException e) {
1492                 // e.g. wrong public key used
1493                 // return false rather than throwing exception
1494                 return false;
1495             } catch (IllegalBlockSizeException e) {
1496                 throw new SignatureException("doFinal() failed", e);
1497             }
1498         }
1499 
engineSetParameter(String param, Object value)1500         protected void engineSetParameter(String param, Object value)
1501                 throws InvalidParameterException {
1502             throw new InvalidParameterException("Parameters not supported");
1503         }
1504 
engineGetParameter(String param)1505         protected Object engineGetParameter(String param)
1506                 throws InvalidParameterException {
1507             throw new InvalidParameterException("Parameters not supported");
1508         }
1509 
1510     }
1511 
1512 }
1513