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