1 /*
2  * Copyright (c) 1996, 2019, 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.access.JavaSecuritySignatureAccess;
44 import jdk.internal.access.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 {
SharedSecrets.setJavaSecuritySignatureAccess( new JavaSecuritySignatureAccess() { @Override public void initVerify(Signature s, PublicKey publicKey, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { s.initVerify(publicKey, params); } @Override public void initVerify(Signature s, java.security.cert.Certificate certificate, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { s.initVerify(certificate, params); } @Override public void initSign(Signature s, PrivateKey privateKey, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { s.initSign(privateKey, params, random); } })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      */
Signature(String algorithm)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      */
getInstance(String algorithm)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 
getInstance(Instance instance, String algorithm)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("sun.security.pkcs11.P11Signature", TRUE);
319     }
320 
isSpi(Service s)321     private static boolean isSpi(Service s) {
322         if (s.getType().equals("Cipher")) {
323             // must be a CipherSpi, which we can wrap with the CipherAdapter
324             return true;
325         }
326         String className = s.getClassName();
327         Boolean result = signatureInfo.get(className);
328         if (result == null) {
329             try {
330                 Object instance = s.newInstance(null);
331                 // Signature extends SignatureSpi
332                 // so it is a "real" Spi if it is an
333                 // instance of SignatureSpi but not Signature
334                 boolean r = (instance instanceof SignatureSpi)
335                                 && (instance instanceof Signature == false);
336                 if ((debug != null) && (r == false)) {
337                     debug.println("Not a SignatureSpi " + className);
338                     debug.println("Delayed provider selection may not be "
339                         + "available for algorithm " + s.getAlgorithm());
340                 }
341                 result = Boolean.valueOf(r);
342                 signatureInfo.put(className, result);
343             } catch (Exception e) {
344                 // something is wrong, assume not an SPI
345                 return false;
346             }
347         }
348         return result.booleanValue();
349     }
350 
351     /**
352      * Returns a Signature object that implements the specified signature
353      * algorithm.
354      *
355      * <p> A new Signature object encapsulating the
356      * SignatureSpi implementation from the specified provider
357      * is returned.  The specified provider must be registered
358      * in the security provider list.
359      *
360      * <p> Note that the list of registered providers may be retrieved via
361      * the {@link Security#getProviders() Security.getProviders()} method.
362      *
363      * @param algorithm the name of the algorithm requested.
364      * See the Signature section in the <a href=
365      * "{@docRoot}/../specs/security/standard-names.html#signature-algorithms">
366      * Java Security Standard Algorithm Names Specification</a>
367      * for information about standard algorithm names.
368      *
369      * @param provider the name of the provider.
370      *
371      * @return the new {@code Signature} object
372      *
373      * @throws IllegalArgumentException if the provider name is {@code null}
374      *         or empty
375      *
376      * @throws NoSuchAlgorithmException if a {@code SignatureSpi}
377      *         implementation for the specified algorithm is not
378      *         available from the specified provider
379      *
380      * @throws NoSuchProviderException if the specified provider is not
381      *         registered in the security provider list
382      *
383      * @throws NullPointerException if {@code algorithm} is {@code null}
384      *
385      * @see Provider
386      */
getInstance(String algorithm, String provider)387     public static Signature getInstance(String algorithm, String provider)
388             throws NoSuchAlgorithmException, NoSuchProviderException {
389         Objects.requireNonNull(algorithm, "null algorithm name");
390         if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
391             // exception compatibility with existing code
392             if (provider == null || provider.isEmpty()) {
393                 throw new IllegalArgumentException("missing provider");
394             }
395             Provider p = Security.getProvider(provider);
396             if (p == null) {
397                 throw new NoSuchProviderException
398                     ("no such provider: " + provider);
399             }
400             return getInstanceRSA(p);
401         }
402         Instance instance = GetInstance.getInstance
403                 ("Signature", SignatureSpi.class, algorithm, provider);
404         return getInstance(instance, algorithm);
405     }
406 
407     /**
408      * Returns a Signature object that implements the specified
409      * signature algorithm.
410      *
411      * <p> A new Signature object encapsulating the
412      * SignatureSpi implementation from the specified Provider
413      * object is returned.  Note that the specified Provider object
414      * does not have to be registered in the provider list.
415      *
416      * @param algorithm the name of the algorithm requested.
417      * See the Signature section in the <a href=
418      * "{@docRoot}/../specs/security/standard-names.html#signature-algorithms">
419      * Java Security Standard Algorithm Names Specification</a>
420      * for information about standard algorithm names.
421      *
422      * @param provider the provider.
423      *
424      * @return the new {@code Signature} object
425      *
426      * @throws IllegalArgumentException if the provider is {@code null}
427      *
428      * @throws NoSuchAlgorithmException if a {@code SignatureSpi}
429      *         implementation for the specified algorithm is not available
430      *         from the specified {@code Provider} object
431      *
432      * @throws NullPointerException if {@code algorithm} is {@code null}
433      *
434      * @see Provider
435      *
436      * @since 1.4
437      */
getInstance(String algorithm, Provider provider)438     public static Signature getInstance(String algorithm, Provider provider)
439             throws NoSuchAlgorithmException {
440         Objects.requireNonNull(algorithm, "null algorithm name");
441         if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
442             // exception compatibility with existing code
443             if (provider == null) {
444                 throw new IllegalArgumentException("missing provider");
445             }
446             return getInstanceRSA(provider);
447         }
448         Instance instance = GetInstance.getInstance
449                 ("Signature", SignatureSpi.class, algorithm, provider);
450         return getInstance(instance, algorithm);
451     }
452 
453     // return an implementation for NONEwithRSA, which is a special case
454     // because of the Cipher.RSA/ECB/PKCS1Padding compatibility wrapper
getInstanceRSA(Provider p)455     private static Signature getInstanceRSA(Provider p)
456             throws NoSuchAlgorithmException {
457         // try Signature first
458         Service s = p.getService("Signature", RSA_SIGNATURE);
459         if (s != null) {
460             Instance instance = GetInstance.getInstance(s, SignatureSpi.class);
461             return getInstance(instance, RSA_SIGNATURE);
462         }
463         // check Cipher
464         try {
465             Cipher c = Cipher.getInstance(RSA_CIPHER, p);
466             return new Delegate(new CipherAdapter(c), RSA_SIGNATURE);
467         } catch (GeneralSecurityException e) {
468             // throw Signature style exception message to avoid confusion,
469             // but append Cipher exception as cause
470             throw new NoSuchAlgorithmException("no such algorithm: "
471                 + RSA_SIGNATURE + " for provider " + p.getName(), e);
472         }
473     }
474 
475     /**
476      * Returns the provider of this signature object.
477      *
478      * @return the provider of this signature object
479      */
getProvider()480     public final Provider getProvider() {
481         chooseFirstProvider();
482         return this.provider;
483     }
484 
getProviderName()485     private String getProviderName() {
486         return (provider == null)  ? "(no provider)" : provider.getName();
487     }
488 
chooseFirstProvider()489     void chooseFirstProvider() {
490         // empty, overridden in Delegate
491     }
492 
493     /**
494      * Initializes this object for verification. If this method is called
495      * again with a different argument, it negates the effect
496      * of this call.
497      *
498      * @param publicKey the public key of the identity whose signature is
499      * going to be verified.
500      *
501      * @throws    InvalidKeyException if the key is invalid.
502      */
initVerify(PublicKey publicKey)503     public final void initVerify(PublicKey publicKey)
504             throws InvalidKeyException {
505         engineInitVerify(publicKey);
506         state = VERIFY;
507 
508         if (!skipDebug && pdebug != null) {
509             pdebug.println("Signature." + algorithm +
510                 " verification algorithm from: " + getProviderName());
511         }
512     }
513 
514     /**
515      * Initialize this object for verification. If this method is called
516      * again with different arguments, it negates the effect
517      * of this call.
518      *
519      * @param publicKey the public key of the identity whose signature is
520      * going to be verified.
521      * @param params the parameters used for verifying this signature.
522      *
523      * @throws    InvalidKeyException if the key is invalid.
524      * @throws    InvalidAlgorithmParameterException if the params is invalid.
525      */
initVerify(PublicKey publicKey, AlgorithmParameterSpec params)526     final void initVerify(PublicKey publicKey, AlgorithmParameterSpec params)
527             throws InvalidKeyException, InvalidAlgorithmParameterException {
528         engineInitVerify(publicKey, params);
529         state = VERIFY;
530 
531         if (!skipDebug && pdebug != null) {
532             pdebug.println("Signature." + algorithm +
533                 " verification algorithm from: " + getProviderName());
534         }
535     }
536 
getPublicKeyFromCert(Certificate cert)537     private static PublicKey getPublicKeyFromCert(Certificate cert)
538             throws InvalidKeyException {
539         // If the certificate is of type X509Certificate,
540         // we should check whether it has a Key Usage
541         // extension marked as critical.
542         //if (cert instanceof java.security.cert.X509Certificate) {
543         if (cert instanceof X509Certificate) {
544             // Check whether the cert has a key usage extension
545             // marked as a critical extension.
546             // The OID for KeyUsage extension is 2.5.29.15.
547             X509Certificate c = (X509Certificate)cert;
548             Set<String> critSet = c.getCriticalExtensionOIDs();
549 
550             if (critSet != null && !critSet.isEmpty()
551                 && critSet.contains("2.5.29.15")) {
552                 boolean[] keyUsageInfo = c.getKeyUsage();
553                 // keyUsageInfo[0] is for digitalSignature.
554                 if ((keyUsageInfo != null) && (keyUsageInfo[0] == false))
555                     throw new InvalidKeyException("Wrong key usage");
556             }
557         }
558         return cert.getPublicKey();
559     }
560 
561     /**
562      * Initializes this object for verification, using the public key from
563      * the given certificate.
564      * <p>If the certificate is of type X.509 and has a <i>key usage</i>
565      * extension field marked as critical, and the value of the <i>key usage</i>
566      * extension field implies that the public key in
567      * the certificate and its corresponding private key are not
568      * supposed to be used for digital signatures, an
569      * {@code InvalidKeyException} is thrown.
570      *
571      * @param certificate the certificate of the identity whose signature is
572      * going to be verified.
573      *
574      * @throws    InvalidKeyException  if the public key in the certificate
575      * is not encoded properly or does not include required  parameter
576      * information or cannot be used for digital signature purposes.
577      * @since 1.3
578      */
initVerify(Certificate certificate)579     public final void initVerify(Certificate certificate)
580             throws InvalidKeyException {
581         engineInitVerify(getPublicKeyFromCert(certificate));
582         state = VERIFY;
583 
584         if (!skipDebug && pdebug != null) {
585             pdebug.println("Signature." + algorithm +
586                 " verification algorithm from: " + getProviderName());
587         }
588     }
589 
590     /**
591      * Initializes this object for verification, using the public key from
592      * the given certificate.
593      * <p>If the certificate is of type X.509 and has a <i>key usage</i>
594      * extension field marked as critical, and the value of the <i>key usage</i>
595      * extension field implies that the public key in
596      * the certificate and its corresponding private key are not
597      * supposed to be used for digital signatures, an
598      * {@code InvalidKeyException} is thrown.
599      *
600      * @param certificate the certificate of the identity whose signature is
601      * going to be verified.
602      * @param params the parameters used for verifying this signature.
603      *
604      * @throws    InvalidKeyException  if the public key in the certificate
605      * is not encoded properly or does not include required  parameter
606      * information or cannot be used for digital signature purposes.
607      * @throws    InvalidAlgorithmParameterException if the params is invalid.
608      *
609      * @since 13
610      */
initVerify(Certificate certificate, AlgorithmParameterSpec params)611     final void initVerify(Certificate certificate,
612             AlgorithmParameterSpec params)
613             throws InvalidKeyException, InvalidAlgorithmParameterException {
614         engineInitVerify(getPublicKeyFromCert(certificate), params);
615         state = VERIFY;
616 
617         if (!skipDebug && pdebug != null) {
618             pdebug.println("Signature." + algorithm +
619                 " verification algorithm from: " + getProviderName());
620         }
621     }
622 
623     /**
624      * Initialize this object for signing. If this method is called
625      * again with a different argument, it negates the effect
626      * of this call.
627      *
628      * @param privateKey the private key of the identity whose signature
629      * is going to be generated.
630      *
631      * @throws    InvalidKeyException if the key is invalid.
632      */
initSign(PrivateKey privateKey)633     public final void initSign(PrivateKey privateKey)
634             throws InvalidKeyException {
635         engineInitSign(privateKey);
636         state = SIGN;
637 
638         if (!skipDebug && pdebug != null) {
639             pdebug.println("Signature." + algorithm +
640                 " signing algorithm from: " + getProviderName());
641         }
642     }
643 
644     /**
645      * Initialize this object for signing. If this method is called
646      * again with a different argument, it negates the effect
647      * of this call.
648      *
649      * @param privateKey the private key of the identity whose signature
650      * is going to be generated.
651      *
652      * @param random the source of randomness for this signature.
653      *
654      * @throws    InvalidKeyException if the key is invalid.
655      */
initSign(PrivateKey privateKey, SecureRandom random)656     public final void initSign(PrivateKey privateKey, SecureRandom random)
657             throws InvalidKeyException {
658         engineInitSign(privateKey, random);
659         state = SIGN;
660 
661         if (!skipDebug && pdebug != null) {
662             pdebug.println("Signature." + algorithm +
663                 " signing algorithm from: " + getProviderName());
664         }
665     }
666 
667     /**
668      * Initialize this object for signing. If this method is called
669      * again with different arguments, it negates the effect
670      * of this call.
671      *
672      * @param privateKey the private key of the identity whose signature
673      * is going to be generated.
674      * @param params the parameters used for generating signature.
675      * @param random the source of randomness for this signature.
676      *
677      * @throws    InvalidKeyException if the key is invalid.
678      * @throws    InvalidAlgorithmParameterException if the params is invalid
679      */
initSign(PrivateKey privateKey, AlgorithmParameterSpec params, SecureRandom random)680     final void initSign(PrivateKey privateKey,
681             AlgorithmParameterSpec params, SecureRandom random)
682             throws InvalidKeyException, InvalidAlgorithmParameterException {
683         engineInitSign(privateKey, params, random);
684         state = SIGN;
685 
686         if (!skipDebug && pdebug != null) {
687             pdebug.println("Signature." + algorithm +
688                 " signing algorithm from: " + getProviderName());
689         }
690     }
691 
692     /**
693      * Returns the signature bytes of all the data updated.
694      * The format of the signature depends on the underlying
695      * signature scheme.
696      *
697      * <p>A call to this method resets this signature object to the state
698      * it was in when previously initialized for signing via a
699      * call to {@code initSign(PrivateKey)}. That is, the object is
700      * reset and available to generate another signature from the same
701      * signer, if desired, via new calls to {@code update} and
702      * {@code sign}.
703      *
704      * @return the signature bytes of the signing operation's result.
705      *
706      * @throws    SignatureException if this signature object is not
707      * initialized properly or if this signature algorithm is unable to
708      * process the input data provided.
709      */
sign()710     public final byte[] sign() throws SignatureException {
711         if (state == SIGN) {
712             return engineSign();
713         }
714         throw new SignatureException("object not initialized for " +
715                                      "signing");
716     }
717 
718     /**
719      * Finishes the signature operation and stores the resulting signature
720      * bytes in the provided buffer {@code outbuf}, starting at
721      * {@code offset}.
722      * The format of the signature depends on the underlying
723      * signature scheme.
724      *
725      * <p>This signature object is reset to its initial state (the state it
726      * was in after a call to one of the {@code initSign} methods) and
727      * can be reused to generate further signatures with the same private key.
728      *
729      * @param outbuf buffer for the signature result.
730      *
731      * @param offset offset into {@code outbuf} where the signature is
732      * stored.
733      *
734      * @param len number of bytes within {@code outbuf} allotted for the
735      * signature.
736      *
737      * @return the number of bytes placed into {@code outbuf}.
738      *
739      * @throws    SignatureException if this signature object is not
740      *     initialized properly, if this signature algorithm is unable to
741      *     process the input data provided, or if {@code len} is less
742      *     than the actual signature length.
743      * @throws    IllegalArgumentException if {@code outbuf} is {@code null},
744      *     or {@code offset} or {@code len} is less than 0, or the sum of
745      *     {@code offset} and {@code len} is greater than the length of
746      *     {@code outbuf}.
747      *
748      * @since 1.2
749      */
sign(byte[] outbuf, int offset, int len)750     public final int sign(byte[] outbuf, int offset, int len)
751         throws SignatureException {
752         if (outbuf == null) {
753             throw new IllegalArgumentException("No output buffer given");
754         }
755         if (offset < 0 || len < 0) {
756             throw new IllegalArgumentException("offset or len is less than 0");
757         }
758         if (outbuf.length - offset < len) {
759             throw new IllegalArgumentException
760                 ("Output buffer too small for specified offset and length");
761         }
762         if (state != SIGN) {
763             throw new SignatureException("object not initialized for " +
764                                          "signing");
765         }
766         return engineSign(outbuf, offset, len);
767     }
768 
769     /**
770      * Verifies the passed-in signature.
771      *
772      * <p>A call to this method resets this signature object to the state
773      * it was in when previously initialized for verification via a
774      * call to {@code initVerify(PublicKey)}. That is, the object is
775      * reset and available to verify another signature from the identity
776      * whose public key was specified in the call to {@code initVerify}.
777      *
778      * @param signature the signature bytes to be verified.
779      *
780      * @return true if the signature was verified, false if not.
781      *
782      * @throws    SignatureException if this signature object is not
783      * initialized properly, the passed-in signature is improperly
784      * encoded or of the wrong type, if this signature algorithm is unable to
785      * process the input data provided, etc.
786      */
verify(byte[] signature)787     public final boolean verify(byte[] signature) throws SignatureException {
788         if (state == VERIFY) {
789             return engineVerify(signature);
790         }
791         throw new SignatureException("object not initialized for " +
792                                      "verification");
793     }
794 
795     /**
796      * Verifies the passed-in signature in the specified array
797      * of bytes, starting at the specified offset.
798      *
799      * <p>A call to this method resets this signature object to the state
800      * it was in when previously initialized for verification via a
801      * call to {@code initVerify(PublicKey)}. That is, the object is
802      * reset and available to verify another signature from the identity
803      * whose public key was specified in the call to {@code initVerify}.
804      *
805      *
806      * @param signature the signature bytes to be verified.
807      * @param offset the offset to start from in the array of bytes.
808      * @param length the number of bytes to use, starting at offset.
809      *
810      * @return true if the signature was verified, false if not.
811      *
812      * @throws    SignatureException if this signature object is not
813      * initialized properly, the passed-in signature is improperly
814      * encoded or of the wrong type, if this signature algorithm is unable to
815      * process the input data provided, etc.
816      * @throws    IllegalArgumentException if the {@code signature}
817      * byte array is {@code null}, or the {@code offset} or {@code length}
818      * is less than 0, or the sum of the {@code offset} and
819      * {@code length} is greater than the length of the
820      * {@code signature} byte array.
821      * @since 1.4
822      */
verify(byte[] signature, int offset, int length)823     public final boolean verify(byte[] signature, int offset, int length)
824         throws SignatureException {
825         if (state == VERIFY) {
826             if (signature == null) {
827                 throw new IllegalArgumentException("signature is null");
828             }
829             if (offset < 0 || length < 0) {
830                 throw new IllegalArgumentException
831                     ("offset or length is less than 0");
832             }
833             if (signature.length - offset < length) {
834                 throw new IllegalArgumentException
835                     ("signature too small for specified offset and length");
836             }
837 
838             return engineVerify(signature, offset, length);
839         }
840         throw new SignatureException("object not initialized for " +
841                                      "verification");
842     }
843 
844     /**
845      * Updates the data to be signed or verified by a byte.
846      *
847      * @param b the byte to use for the update.
848      *
849      * @throws    SignatureException if this signature object is not
850      * initialized properly.
851      */
update(byte b)852     public final void update(byte b) throws SignatureException {
853         if (state == VERIFY || state == SIGN) {
854             engineUpdate(b);
855         } else {
856             throw new SignatureException("object not initialized for "
857                                          + "signature or verification");
858         }
859     }
860 
861     /**
862      * Updates the data to be signed or verified, using the specified
863      * array of bytes.
864      *
865      * @param data the byte array to use for the update.
866      *
867      * @throws    SignatureException if this signature object is not
868      * initialized properly.
869      */
update(byte[] data)870     public final void update(byte[] data) throws SignatureException {
871         update(data, 0, data.length);
872     }
873 
874     /**
875      * Updates the data to be signed or verified, using the specified
876      * array of bytes, starting at the specified offset.
877      *
878      * @param data the array of bytes.
879      * @param off the offset to start from in the array of bytes.
880      * @param len the number of bytes to use, starting at offset.
881      *
882      * @throws    SignatureException if this signature object is not
883      *     initialized properly.
884      * @throws    IllegalArgumentException if {@code data} is {@code null},
885      *     or {@code off} or {@code len} is less than 0, or the sum of
886      *     {@code off} and {@code len} is greater than the length of
887      *     {@code data}.
888      */
update(byte[] data, int off, int len)889     public final void update(byte[] data, int off, int len)
890             throws SignatureException {
891         if (state == SIGN || state == VERIFY) {
892             if (data == null) {
893                 throw new IllegalArgumentException("data is null");
894             }
895             if (off < 0 || len < 0) {
896                 throw new IllegalArgumentException("off or len is less than 0");
897             }
898             if (data.length - off < len) {
899                 throw new IllegalArgumentException
900                     ("data too small for specified offset and length");
901             }
902             engineUpdate(data, off, len);
903         } else {
904             throw new SignatureException("object not initialized for "
905                                          + "signature or verification");
906         }
907     }
908 
909     /**
910      * Updates the data to be signed or verified using the specified
911      * ByteBuffer. Processes the {@code data.remaining()} bytes
912      * starting at {@code data.position()}.
913      * Upon return, the buffer's position will be equal to its limit;
914      * its limit will not have changed.
915      *
916      * @param data the ByteBuffer
917      *
918      * @throws    SignatureException if this signature object is not
919      * initialized properly.
920      * @since 1.5
921      */
update(ByteBuffer data)922     public final void update(ByteBuffer data) throws SignatureException {
923         if ((state != SIGN) && (state != VERIFY)) {
924             throw new SignatureException("object not initialized for "
925                                          + "signature or verification");
926         }
927         if (data == null) {
928             throw new NullPointerException();
929         }
930         engineUpdate(data);
931     }
932 
933     /**
934      * Returns the name of the algorithm for this signature object.
935      *
936      * @return the name of the algorithm for this signature object.
937      */
getAlgorithm()938     public final String getAlgorithm() {
939         return this.algorithm;
940     }
941 
942     /**
943      * Returns a string representation of this signature object,
944      * providing information that includes the state of the object
945      * and the name of the algorithm used.
946      *
947      * @return a string representation of this signature object.
948      */
toString()949     public String toString() {
950         String initState = "";
951         switch (state) {
952         case UNINITIALIZED:
953             initState = "<not initialized>";
954             break;
955         case VERIFY:
956             initState = "<initialized for verifying>";
957             break;
958         case SIGN:
959             initState = "<initialized for signing>";
960             break;
961         }
962         return "Signature object: " + getAlgorithm() + initState;
963     }
964 
965     /**
966      * Sets the specified algorithm parameter to the specified value.
967      * This method supplies a general-purpose mechanism through
968      * which it is possible to set the various parameters of this object.
969      * A parameter may be any settable parameter for the algorithm, such as
970      * a parameter size, or a source of random bits for signature generation
971      * (if appropriate), or an indication of whether or not to perform
972      * a specific but optional computation. A uniform algorithm-specific
973      * naming scheme for each parameter is desirable but left unspecified
974      * at this time.
975      *
976      * @param param the string identifier of the parameter.
977      * @param value the parameter value.
978      *
979      * @throws    InvalidParameterException if {@code param} is an
980      * invalid parameter for this signature algorithm engine,
981      * the parameter is already set
982      * and cannot be set again, a security exception occurs, and so on.
983      *
984      * @see #getParameter
985      *
986      * @deprecated Use
987      * {@link #setParameter(java.security.spec.AlgorithmParameterSpec)
988      * setParameter}.
989      */
990     @Deprecated
setParameter(String param, Object value)991     public final void setParameter(String param, Object value)
992             throws InvalidParameterException {
993         engineSetParameter(param, value);
994     }
995 
996     /**
997      * Initializes this signature engine with the specified parameter set.
998      *
999      * @param params the parameters
1000      *
1001      * @throws    InvalidAlgorithmParameterException if the given parameters
1002      * are inappropriate for this signature engine
1003      *
1004      * @see #getParameters
1005      */
setParameter(AlgorithmParameterSpec params)1006     public final void setParameter(AlgorithmParameterSpec params)
1007             throws InvalidAlgorithmParameterException {
1008         engineSetParameter(params);
1009     }
1010 
1011     /**
1012      * Returns the parameters used with this signature object.
1013      *
1014      * <p> If this signature has been previously initialized with parameters
1015      * (by calling the {@code setParameter} method), this method returns
1016      * the same parameters. If this signature has not been initialized with
1017      * parameters, this method may return a combination of default and
1018      * randomly generated parameter values if the underlying
1019      * signature implementation supports it and can successfully generate
1020      * them. Otherwise, {@code null} is returned.
1021      *
1022      * @return the parameters used with this signature, or {@code null}
1023      *
1024      * @see #setParameter(AlgorithmParameterSpec)
1025      * @since 1.4
1026      */
getParameters()1027     public final AlgorithmParameters getParameters() {
1028         return engineGetParameters();
1029     }
1030 
1031     /**
1032      * Gets the value of the specified algorithm parameter. This method
1033      * supplies a general-purpose mechanism through which it is possible to
1034      * get the various parameters of this object. A parameter may be any
1035      * settable parameter for the algorithm, such as a parameter size, or
1036      * a source of random bits for signature generation (if appropriate),
1037      * or an indication of whether or not to perform a specific but optional
1038      * computation. A uniform algorithm-specific naming scheme for each
1039      * parameter is desirable but left unspecified at this time.
1040      *
1041      * @param param the string name of the parameter.
1042      *
1043      * @return the object that represents the parameter value, or {@code null} if
1044      * there is none.
1045      *
1046      * @throws    InvalidParameterException if {@code param} is an invalid
1047      * parameter for this engine, or another exception occurs while
1048      * trying to get this parameter.
1049      *
1050      * @see #setParameter(String, Object)
1051      *
1052      * @deprecated
1053      */
1054     @Deprecated
getParameter(String param)1055     public final Object getParameter(String param)
1056             throws InvalidParameterException {
1057         return engineGetParameter(param);
1058     }
1059 
1060     /**
1061      * Returns a clone if the implementation is cloneable.
1062      *
1063      * @return a clone if the implementation is cloneable.
1064      *
1065      * @throws    CloneNotSupportedException if this is called
1066      * on an implementation that does not support {@code Cloneable}.
1067      */
clone()1068     public Object clone() throws CloneNotSupportedException {
1069         if (this instanceof Cloneable) {
1070             return super.clone();
1071         } else {
1072             throw new CloneNotSupportedException();
1073         }
1074     }
1075 
1076     /*
1077      * The following class allows providers to extend from SignatureSpi
1078      * rather than from Signature. It represents a Signature with an
1079      * encapsulated, provider-supplied SPI object (of type SignatureSpi).
1080      * If the provider implementation is an instance of SignatureSpi, the
1081      * getInstance() methods above return an instance of this class, with
1082      * the SPI object encapsulated.
1083      *
1084      * Note: All SPI methods from the original Signature class have been
1085      * moved up the hierarchy into a new class (SignatureSpi), which has
1086      * been interposed in the hierarchy between the API (Signature)
1087      * and its original parent (Object).
1088      */
1089 
1090     @SuppressWarnings("deprecation")
1091     private static class Delegate extends Signature {
1092 
1093         // The provider implementation (delegate)
1094         // filled in once the provider is selected
1095         private SignatureSpi sigSpi;
1096 
1097         // lock for mutex during provider selection
1098         private final Object lock;
1099 
1100         // next service to try in provider selection
1101         // null once provider is selected
1102         private Service firstService;
1103 
1104         // remaining services to try in provider selection
1105         // null once provider is selected
1106         private Iterator<Service> serviceIterator;
1107 
1108         // constructor
Delegate(SignatureSpi sigSpi, String algorithm)1109         Delegate(SignatureSpi sigSpi, String algorithm) {
1110             super(algorithm);
1111             this.sigSpi = sigSpi;
1112             this.lock = null; // no lock needed
1113         }
1114 
1115         // used with delayed provider selection
Delegate(Service service, Iterator<Service> iterator, String algorithm)1116         Delegate(Service service,
1117                         Iterator<Service> iterator, String algorithm) {
1118             super(algorithm);
1119             this.firstService = service;
1120             this.serviceIterator = iterator;
1121             this.lock = new Object();
1122         }
1123 
1124         /**
1125          * Returns a clone if the delegate is cloneable.
1126          *
1127          * @return a clone if the delegate is cloneable.
1128          *
1129          * @throws    CloneNotSupportedException if this is called on a
1130          * delegate that does not support {@code Cloneable}.
1131          */
clone()1132         public Object clone() throws CloneNotSupportedException {
1133             chooseFirstProvider();
1134             if (sigSpi instanceof Cloneable) {
1135                 SignatureSpi sigSpiClone = (SignatureSpi)sigSpi.clone();
1136                 // Because 'algorithm' and 'provider' are private
1137                 // members of our supertype, we must perform a cast to
1138                 // access them.
1139                 Signature that =
1140                     new Delegate(sigSpiClone, ((Signature)this).algorithm);
1141                 that.provider = ((Signature)this).provider;
1142                 return that;
1143             } else {
1144                 throw new CloneNotSupportedException();
1145             }
1146         }
1147 
newInstance(Service s)1148         private static SignatureSpi newInstance(Service s)
1149                 throws NoSuchAlgorithmException {
1150             if (s.getType().equals("Cipher")) {
1151                 // must be NONEwithRSA
1152                 try {
1153                     Cipher c = Cipher.getInstance(RSA_CIPHER, s.getProvider());
1154                     return new CipherAdapter(c);
1155                 } catch (NoSuchPaddingException e) {
1156                     throw new NoSuchAlgorithmException(e);
1157                 }
1158             } else {
1159                 Object o = s.newInstance(null);
1160                 if (o instanceof SignatureSpi == false) {
1161                     throw new NoSuchAlgorithmException
1162                         ("Not a SignatureSpi: " + o.getClass().getName());
1163                 }
1164                 return (SignatureSpi)o;
1165             }
1166         }
1167 
1168         // max number of debug warnings to print from chooseFirstProvider()
1169         private static int warnCount = 10;
1170 
1171         /**
1172          * Choose the Spi from the first provider available. Used if
1173          * delayed provider selection is not possible because initSign()/
1174          * initVerify() is not the first method called.
1175          */
chooseFirstProvider()1176         void chooseFirstProvider() {
1177             if (sigSpi != null) {
1178                 return;
1179             }
1180             synchronized (lock) {
1181                 if (sigSpi != null) {
1182                     return;
1183                 }
1184                 if (debug != null) {
1185                     int w = --warnCount;
1186                     if (w >= 0) {
1187                         debug.println("Signature.init() not first method "
1188                             + "called, disabling delayed provider selection");
1189                         if (w == 0) {
1190                             debug.println("Further warnings of this type will "
1191                                 + "be suppressed");
1192                         }
1193                         new Exception("Debug call trace").printStackTrace();
1194                     }
1195                 }
1196                 Exception lastException = null;
1197                 while ((firstService != null) || serviceIterator.hasNext()) {
1198                     Service s;
1199                     if (firstService != null) {
1200                         s = firstService;
1201                         firstService = null;
1202                     } else {
1203                         s = serviceIterator.next();
1204                     }
1205                     if (isSpi(s) == false) {
1206                         continue;
1207                     }
1208                     try {
1209                         sigSpi = newInstance(s);
1210                         provider = s.getProvider();
1211                         // not needed any more
1212                         firstService = null;
1213                         serviceIterator = null;
1214                         return;
1215                     } catch (NoSuchAlgorithmException e) {
1216                         lastException = e;
1217                     }
1218                 }
1219                 ProviderException e = new ProviderException
1220                         ("Could not construct SignatureSpi instance");
1221                 if (lastException != null) {
1222                     e.initCause(lastException);
1223                 }
1224                 throw e;
1225             }
1226         }
1227 
1228         // Used by engineSetParameter/engineInitSign/engineInitVerify() to
1229         // find the right provider with the supplied key, parameters, random source
chooseProvider(int type, Key key, AlgorithmParameterSpec params, SecureRandom random)1230         private void chooseProvider(int type, Key key,
1231                 AlgorithmParameterSpec params, SecureRandom random)
1232                 throws InvalidKeyException, InvalidAlgorithmParameterException {
1233             synchronized (lock) {
1234                 if (sigSpi != null) {
1235                     return;
1236                 }
1237                 Exception lastException = null;
1238                 while ((firstService != null) || serviceIterator.hasNext()) {
1239                     Service s;
1240                     if (firstService != null) {
1241                         s = firstService;
1242                         firstService = null;
1243                     } else {
1244                         s = serviceIterator.next();
1245                     }
1246                     // if provider says it does not support this key, ignore it
1247                     if (key != null && s.supportsParameter(key) == false) {
1248                         continue;
1249                     }
1250                     // if instance is not a SignatureSpi, ignore it
1251                     if (isSpi(s) == false) {
1252                         continue;
1253                     }
1254                     try {
1255                         SignatureSpi spi = newInstance(s);
1256                         tryOperation(spi, type, key, params, random);
1257                         provider = s.getProvider();
1258                         sigSpi = spi;
1259                         firstService = null;
1260                         serviceIterator = null;
1261                         return;
1262                     } catch (Exception e) {
1263                         // NoSuchAlgorithmException from newInstance()
1264                         // InvalidKeyException from init()
1265                         // RuntimeException (ProviderException) from init()
1266                         if (lastException == null) {
1267                             lastException = e;
1268                         }
1269                     }
1270                 }
1271                 // no working provider found, fail
1272                 if (lastException instanceof InvalidKeyException) {
1273                     throw (InvalidKeyException)lastException;
1274                 }
1275                 if (lastException instanceof RuntimeException) {
1276                     throw (RuntimeException)lastException;
1277                 }
1278                 if (lastException instanceof InvalidAlgorithmParameterException) {
1279                     throw (InvalidAlgorithmParameterException)lastException;
1280                 }
1281 
1282                 String k = (key != null) ? key.getClass().getName() : "(null)";
1283                 throw new InvalidKeyException
1284                     ("No installed provider supports this key: "
1285                     + k, lastException);
1286             }
1287         }
1288 
1289         private static final int I_PUB           = 1;
1290         private static final int I_PRIV          = 2;
1291         private static final int I_PRIV_SR       = 3;
1292         private static final int I_PUB_PARAM     = 4;
1293         private static final int I_PRIV_PARAM_SR = 5;
1294         private static final int S_PARAM         = 6;
1295 
tryOperation(SignatureSpi spi, int type, Key key, AlgorithmParameterSpec params, SecureRandom random)1296         private void tryOperation(SignatureSpi spi, int type, Key  key,
1297                 AlgorithmParameterSpec params, SecureRandom random)
1298                 throws InvalidKeyException, InvalidAlgorithmParameterException {
1299             switch (type) {
1300             case I_PUB:
1301                 spi.engineInitVerify((PublicKey)key);
1302                 break;
1303             case I_PUB_PARAM:
1304                 spi.engineInitVerify((PublicKey)key, params);
1305                 break;
1306             case I_PRIV:
1307                 spi.engineInitSign((PrivateKey)key);
1308                 break;
1309             case I_PRIV_SR:
1310                 spi.engineInitSign((PrivateKey)key, random);
1311                 break;
1312             case I_PRIV_PARAM_SR:
1313                 spi.engineInitSign((PrivateKey)key, params, random);
1314                 break;
1315             case S_PARAM:
1316                 spi.engineSetParameter(params);
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) {
1326                 sigSpi.engineInitVerify(publicKey);
1327             } else {
1328                 try {
1329                     chooseProvider(I_PUB, publicKey, null, null);
1330                 } catch (InvalidAlgorithmParameterException iape) {
1331                     // should not happen, re-throw as IKE just in case
1332                     throw new InvalidKeyException(iape);
1333                 }
1334             }
1335         }
1336 
engineInitVerify(PublicKey publicKey, AlgorithmParameterSpec params)1337         void engineInitVerify(PublicKey publicKey,
1338                 AlgorithmParameterSpec params)
1339                 throws InvalidKeyException, InvalidAlgorithmParameterException {
1340             if (sigSpi != null) {
1341                 sigSpi.engineInitVerify(publicKey, params);
1342             } else {
1343                 chooseProvider(I_PUB_PARAM, publicKey, params, null);
1344             }
1345         }
1346 
engineInitSign(PrivateKey privateKey)1347         protected void engineInitSign(PrivateKey privateKey)
1348                 throws InvalidKeyException {
1349             if (sigSpi != null) {
1350                 sigSpi.engineInitSign(privateKey);
1351             } else {
1352                 try {
1353                     chooseProvider(I_PRIV, privateKey, null, null);
1354                 } catch (InvalidAlgorithmParameterException iape) {
1355                     // should not happen, re-throw as IKE just in case
1356                     throw new InvalidKeyException(iape);
1357                 }
1358             }
1359         }
1360 
engineInitSign(PrivateKey privateKey, SecureRandom sr)1361         protected void engineInitSign(PrivateKey privateKey, SecureRandom sr)
1362                 throws InvalidKeyException {
1363             if (sigSpi != null) {
1364                 sigSpi.engineInitSign(privateKey, sr);
1365             } else {
1366                 try {
1367                     chooseProvider(I_PRIV_SR, privateKey, null, sr);
1368                 } catch (InvalidAlgorithmParameterException iape) {
1369                     // should not happen, re-throw as IKE just in case
1370                     throw new InvalidKeyException(iape);
1371                 }
1372             }
1373         }
1374 
engineInitSign(PrivateKey privateKey, AlgorithmParameterSpec params, SecureRandom sr)1375         void engineInitSign(PrivateKey privateKey,
1376                 AlgorithmParameterSpec params, SecureRandom sr)
1377                 throws InvalidKeyException, InvalidAlgorithmParameterException {
1378             if (sigSpi != null) {
1379                 sigSpi.engineInitSign(privateKey, params, sr);
1380             } else {
1381                 chooseProvider(I_PRIV_PARAM_SR, privateKey, params, sr);
1382             }
1383         }
1384 
engineUpdate(byte b)1385         protected void engineUpdate(byte b) throws SignatureException {
1386             chooseFirstProvider();
1387             sigSpi.engineUpdate(b);
1388         }
1389 
engineUpdate(byte[] b, int off, int len)1390         protected void engineUpdate(byte[] b, int off, int len)
1391                 throws SignatureException {
1392             chooseFirstProvider();
1393             sigSpi.engineUpdate(b, off, len);
1394         }
1395 
engineUpdate(ByteBuffer data)1396         protected void engineUpdate(ByteBuffer data) {
1397             chooseFirstProvider();
1398             sigSpi.engineUpdate(data);
1399         }
1400 
engineSign()1401         protected byte[] engineSign() throws SignatureException {
1402             chooseFirstProvider();
1403             return sigSpi.engineSign();
1404         }
1405 
engineSign(byte[] outbuf, int offset, int len)1406         protected int engineSign(byte[] outbuf, int offset, int len)
1407                 throws SignatureException {
1408             chooseFirstProvider();
1409             return sigSpi.engineSign(outbuf, offset, len);
1410         }
1411 
engineVerify(byte[] sigBytes)1412         protected boolean engineVerify(byte[] sigBytes)
1413                 throws SignatureException {
1414             chooseFirstProvider();
1415             return sigSpi.engineVerify(sigBytes);
1416         }
1417 
engineVerify(byte[] sigBytes, int offset, int length)1418         protected boolean engineVerify(byte[] sigBytes, int offset, int length)
1419                 throws SignatureException {
1420             chooseFirstProvider();
1421             return sigSpi.engineVerify(sigBytes, offset, length);
1422         }
1423 
engineSetParameter(String param, Object value)1424         protected void engineSetParameter(String param, Object value)
1425                 throws InvalidParameterException {
1426             chooseFirstProvider();
1427             sigSpi.engineSetParameter(param, value);
1428         }
1429 
engineSetParameter(AlgorithmParameterSpec params)1430         protected void engineSetParameter(AlgorithmParameterSpec params)
1431                 throws InvalidAlgorithmParameterException {
1432             if (sigSpi != null) {
1433                 sigSpi.engineSetParameter(params);
1434             } else {
1435                 try {
1436                     chooseProvider(S_PARAM, null, params, null);
1437                 } catch (InvalidKeyException ike) {
1438                     // should never happen, rethrow just in case
1439                     throw new InvalidAlgorithmParameterException(ike);
1440                 }
1441             }
1442         }
1443 
engineGetParameter(String param)1444         protected Object engineGetParameter(String param)
1445                 throws InvalidParameterException {
1446             chooseFirstProvider();
1447             return sigSpi.engineGetParameter(param);
1448         }
1449 
engineGetParameters()1450         protected AlgorithmParameters engineGetParameters() {
1451             chooseFirstProvider();
1452             return sigSpi.engineGetParameters();
1453         }
1454     }
1455 
1456     // adapter for RSA/ECB/PKCS1Padding ciphers
1457     @SuppressWarnings("deprecation")
1458     private static class CipherAdapter extends SignatureSpi {
1459 
1460         private final Cipher cipher;
1461 
1462         private ByteArrayOutputStream data;
1463 
CipherAdapter(Cipher cipher)1464         CipherAdapter(Cipher cipher) {
1465             this.cipher = cipher;
1466         }
1467 
engineInitVerify(PublicKey publicKey)1468         protected void engineInitVerify(PublicKey publicKey)
1469                 throws InvalidKeyException {
1470             cipher.init(Cipher.DECRYPT_MODE, publicKey);
1471             if (data == null) {
1472                 data = new ByteArrayOutputStream(128);
1473             } else {
1474                 data.reset();
1475             }
1476         }
1477 
engineInitSign(PrivateKey privateKey)1478         protected void engineInitSign(PrivateKey privateKey)
1479                 throws InvalidKeyException {
1480             cipher.init(Cipher.ENCRYPT_MODE, privateKey);
1481             data = null;
1482         }
1483 
engineInitSign(PrivateKey privateKey, SecureRandom random)1484         protected void engineInitSign(PrivateKey privateKey,
1485                 SecureRandom random) throws InvalidKeyException {
1486             cipher.init(Cipher.ENCRYPT_MODE, privateKey, random);
1487             data = null;
1488         }
1489 
engineUpdate(byte b)1490         protected void engineUpdate(byte b) throws SignatureException {
1491             engineUpdate(new byte[] {b}, 0, 1);
1492         }
1493 
engineUpdate(byte[] b, int off, int len)1494         protected void engineUpdate(byte[] b, int off, int len)
1495                 throws SignatureException {
1496             if (data != null) {
1497                 data.write(b, off, len);
1498                 return;
1499             }
1500             byte[] out = cipher.update(b, off, len);
1501             if ((out != null) && (out.length != 0)) {
1502                 throw new SignatureException
1503                     ("Cipher unexpectedly returned data");
1504             }
1505         }
1506 
engineSign()1507         protected byte[] engineSign() throws SignatureException {
1508             try {
1509                 return cipher.doFinal();
1510             } catch (IllegalBlockSizeException e) {
1511                 throw new SignatureException("doFinal() failed", e);
1512             } catch (BadPaddingException e) {
1513                 throw new SignatureException("doFinal() failed", e);
1514             }
1515         }
1516 
engineVerify(byte[] sigBytes)1517         protected boolean engineVerify(byte[] sigBytes)
1518                 throws SignatureException {
1519             try {
1520                 byte[] out = cipher.doFinal(sigBytes);
1521                 byte[] dataBytes = data.toByteArray();
1522                 data.reset();
1523                 return MessageDigest.isEqual(out, dataBytes);
1524             } catch (BadPaddingException e) {
1525                 // e.g. wrong public key used
1526                 // return false rather than throwing exception
1527                 return false;
1528             } catch (IllegalBlockSizeException e) {
1529                 throw new SignatureException("doFinal() failed", e);
1530             }
1531         }
1532 
engineSetParameter(String param, Object value)1533         protected void engineSetParameter(String param, Object value)
1534                 throws InvalidParameterException {
1535             throw new InvalidParameterException("Parameters not supported");
1536         }
1537 
engineGetParameter(String param)1538         protected Object engineGetParameter(String param)
1539                 throws InvalidParameterException {
1540             throw new InvalidParameterException("Parameters not supported");
1541         }
1542 
1543     }
1544 
1545 }
1546