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 { 124 SharedSecrets.setJavaSecuritySignatureAccess( 125 new JavaSecuritySignatureAccess() { 126 @Override 127 public void initVerify(Signature s, PublicKey publicKey, 128 AlgorithmParameterSpec params) 129 throws InvalidKeyException, 130 InvalidAlgorithmParameterException { 131 s.initVerify(publicKey, params); 132 } 133 @Override 134 public void initVerify(Signature s, 135 java.security.cert.Certificate certificate, 136 AlgorithmParameterSpec params) 137 throws InvalidKeyException, 138 InvalidAlgorithmParameterException { 139 s.initVerify(certificate, params); 140 } 141 @Override 142 public void initSign(Signature s, PrivateKey privateKey, 143 AlgorithmParameterSpec params, SecureRandom random) 144 throws InvalidKeyException, 145 InvalidAlgorithmParameterException { 146 s.initSign(privateKey, params, random); 147 } 148 }); 149 } 150 151 private static final Debug debug = 152 Debug.getInstance("jca", "Signature"); 153 154 private static final Debug pdebug = 155 Debug.getInstance("provider", "Provider"); 156 private static final boolean skipDebug = 157 Debug.isOn("engine=") && !Debug.isOn("signature"); 158 159 /* 160 * The algorithm for this signature object. 161 * This value is used to map an OID to the particular algorithm. 162 * The mapping is done in AlgorithmObject.algOID(String algorithm) 163 */ 164 private String algorithm; 165 166 // The provider 167 Provider provider; 168 169 /** 170 * Possible {@link #state} value, signifying that 171 * this signature object has not yet been initialized. 172 */ 173 protected static final int UNINITIALIZED = 0; 174 175 /** 176 * Possible {@link #state} value, signifying that 177 * this signature object has been initialized for signing. 178 */ 179 protected static final int SIGN = 2; 180 181 /** 182 * Possible {@link #state} value, signifying that 183 * this signature object has been initialized for verification. 184 */ 185 protected static final int VERIFY = 3; 186 187 /** 188 * Current state of this signature object. 189 */ 190 protected int state = UNINITIALIZED; 191 192 /** 193 * Creates a Signature object for the specified algorithm. 194 * 195 * @param algorithm the standard string name of the algorithm. 196 * See the Signature section in the <a href= 197 * "{@docRoot}/../specs/security/standard-names.html#signature-algorithms"> 198 * Java Security Standard Algorithm Names Specification</a> 199 * for information about standard algorithm names. 200 */ 201 protected Signature(String algorithm) { 202 this.algorithm = algorithm; 203 } 204 205 // name of the special signature alg 206 private static final String RSA_SIGNATURE = "NONEwithRSA"; 207 208 // name of the equivalent cipher alg 209 private static final String RSA_CIPHER = "RSA/ECB/PKCS1Padding"; 210 211 // all the services we need to lookup for compatibility with Cipher 212 private static final List<ServiceId> rsaIds = List.of( 213 new ServiceId("Signature", "NONEwithRSA"), 214 new ServiceId("Cipher", "RSA/ECB/PKCS1Padding"), 215 new ServiceId("Cipher", "RSA/ECB"), 216 new ServiceId("Cipher", "RSA//PKCS1Padding"), 217 new ServiceId("Cipher", "RSA")); 218 219 /** 220 * Returns a Signature object that implements the specified signature 221 * algorithm. 222 * 223 * <p> This method traverses the list of registered security Providers, 224 * starting with the most preferred Provider. 225 * A new Signature object encapsulating the 226 * SignatureSpi implementation from the first 227 * Provider that supports the specified algorithm is returned. 228 * 229 * <p> Note that the list of registered providers may be retrieved via 230 * the {@link Security#getProviders() Security.getProviders()} method. 231 * 232 * @implNote 233 * The JDK Reference Implementation additionally uses the 234 * {@code jdk.security.provider.preferred} 235 * {@link Security#getProperty(String) Security} property to determine 236 * the preferred provider order for the specified algorithm. This 237 * may be different than the order of providers returned by 238 * {@link Security#getProviders() Security.getProviders()}. 239 * 240 * @param algorithm the standard name of the algorithm requested. 241 * See the Signature section in the <a href= 242 * "{@docRoot}/../specs/security/standard-names.html#signature-algorithms"> 243 * Java Security Standard Algorithm Names Specification</a> 244 * for information about standard algorithm names. 245 * 246 * @return the new {@code Signature} object 247 * 248 * @throws NoSuchAlgorithmException if no {@code Provider} supports a 249 * {@code Signature} implementation for the 250 * specified algorithm 251 * 252 * @throws NullPointerException if {@code algorithm} is {@code null} 253 * 254 * @see Provider 255 */ 256 public static Signature getInstance(String algorithm) 257 throws NoSuchAlgorithmException { 258 Objects.requireNonNull(algorithm, "null algorithm name"); 259 List<Service> list; 260 if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) { 261 list = GetInstance.getServices(rsaIds); 262 } else { 263 list = GetInstance.getServices("Signature", algorithm); 264 } 265 Iterator<Service> t = list.iterator(); 266 if (t.hasNext() == false) { 267 throw new NoSuchAlgorithmException 268 (algorithm + " Signature not available"); 269 } 270 // try services until we find an Spi or a working Signature subclass 271 NoSuchAlgorithmException failure; 272 do { 273 Service s = t.next(); 274 if (isSpi(s)) { 275 return new Delegate(s, t, algorithm); 276 } else { 277 // must be a subclass of Signature, disable dynamic selection 278 try { 279 Instance instance = 280 GetInstance.getInstance(s, SignatureSpi.class); 281 return getInstance(instance, algorithm); 282 } catch (NoSuchAlgorithmException e) { 283 failure = e; 284 } 285 } 286 } while (t.hasNext()); 287 throw failure; 288 } 289 290 private static Signature getInstance(Instance instance, String algorithm) { 291 Signature sig; 292 if (instance.impl instanceof Signature) { 293 sig = (Signature)instance.impl; 294 sig.algorithm = algorithm; 295 } else { 296 SignatureSpi spi = (SignatureSpi)instance.impl; 297 sig = new Delegate(spi, algorithm); 298 } 299 sig.provider = instance.provider; 300 return sig; 301 } 302 303 private static final Map<String,Boolean> signatureInfo; 304 305 static { 306 signatureInfo = new ConcurrentHashMap<>(); 307 Boolean TRUE = Boolean.TRUE; 308 // pre-initialize with values for our SignatureSpi implementations 309 signatureInfo.put("sun.security.provider.DSA$RawDSA", TRUE); 310 signatureInfo.put("sun.security.provider.DSA$SHA1withDSA", TRUE); 311 signatureInfo.put("sun.security.rsa.RSASignature$MD2withRSA", TRUE); 312 signatureInfo.put("sun.security.rsa.RSASignature$MD5withRSA", TRUE); 313 signatureInfo.put("sun.security.rsa.RSASignature$SHA1withRSA", TRUE); 314 signatureInfo.put("sun.security.rsa.RSASignature$SHA256withRSA", TRUE); 315 signatureInfo.put("sun.security.rsa.RSASignature$SHA384withRSA", TRUE); 316 signatureInfo.put("sun.security.rsa.RSASignature$SHA512withRSA", TRUE); 317 signatureInfo.put("sun.security.rsa.RSAPSSSignature", TRUE); 318 signatureInfo.put("sun.security.pkcs11.P11Signature", TRUE); 319 } 320 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 */ 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 */ 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 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 */ 480 public final Provider getProvider() { 481 chooseFirstProvider(); 482 return this.provider; 483 } 484 485 private String getProviderName() { 486 return (provider == null) ? "(no provider)" : provider.getName(); 487 } 488 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 * @exception InvalidKeyException if the key is invalid. 502 */ 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 * @exception InvalidKeyException if the key is invalid. 524 * @exception InvalidAlgorithmParameterException if the params is invalid. 525 */ 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 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 * @exception 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 */ 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 * @exception 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 * @exception InvalidAlgorithmParameterException if the params is invalid. 608 * 609 * @since 13 610 */ 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 * @exception InvalidKeyException if the key is invalid. 632 */ 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 * @exception InvalidKeyException if the key is invalid. 655 */ 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 * @exception InvalidKeyException if the key is invalid. 678 * @exception InvalidAlgorithmParameterException if the params is invalid 679 */ 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 * @exception 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 */ 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 * @exception 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 * @exception 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 */ 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 * @exception 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 */ 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 * @exception 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 * @exception 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 */ 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 * @exception SignatureException if this signature object is not 850 * initialized properly. 851 */ 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 * @exception SignatureException if this signature object is not 868 * initialized properly. 869 */ 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 * @exception SignatureException if this signature object is not 883 * initialized properly. 884 * @exception 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 */ 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 * @exception SignatureException if this signature object is not 919 * initialized properly. 920 * @since 1.5 921 */ 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 */ 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 */ 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 * @exception 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 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 * @exception InvalidAlgorithmParameterException if the given parameters 1002 * are inappropriate for this signature engine 1003 * 1004 * @see #getParameters 1005 */ 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 */ 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 * @exception 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 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 * @exception CloneNotSupportedException if this is called 1066 * on an implementation that does not support {@code Cloneable}. 1067 */ 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 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 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 * @exception CloneNotSupportedException if this is called on a 1130 * delegate that does not support {@code Cloneable}. 1131 */ 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 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 */ 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 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 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 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 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 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 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 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 1385 protected void engineUpdate(byte b) throws SignatureException { 1386 chooseFirstProvider(); 1387 sigSpi.engineUpdate(b); 1388 } 1389 1390 protected void engineUpdate(byte[] b, int off, int len) 1391 throws SignatureException { 1392 chooseFirstProvider(); 1393 sigSpi.engineUpdate(b, off, len); 1394 } 1395 1396 protected void engineUpdate(ByteBuffer data) { 1397 chooseFirstProvider(); 1398 sigSpi.engineUpdate(data); 1399 } 1400 1401 protected byte[] engineSign() throws SignatureException { 1402 chooseFirstProvider(); 1403 return sigSpi.engineSign(); 1404 } 1405 1406 protected int engineSign(byte[] outbuf, int offset, int len) 1407 throws SignatureException { 1408 chooseFirstProvider(); 1409 return sigSpi.engineSign(outbuf, offset, len); 1410 } 1411 1412 protected boolean engineVerify(byte[] sigBytes) 1413 throws SignatureException { 1414 chooseFirstProvider(); 1415 return sigSpi.engineVerify(sigBytes); 1416 } 1417 1418 protected boolean engineVerify(byte[] sigBytes, int offset, int length) 1419 throws SignatureException { 1420 chooseFirstProvider(); 1421 return sigSpi.engineVerify(sigBytes, offset, length); 1422 } 1423 1424 protected void engineSetParameter(String param, Object value) 1425 throws InvalidParameterException { 1426 chooseFirstProvider(); 1427 sigSpi.engineSetParameter(param, value); 1428 } 1429 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 1444 protected Object engineGetParameter(String param) 1445 throws InvalidParameterException { 1446 chooseFirstProvider(); 1447 return sigSpi.engineGetParameter(param); 1448 } 1449 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 1464 CipherAdapter(Cipher cipher) { 1465 this.cipher = cipher; 1466 } 1467 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 1478 protected void engineInitSign(PrivateKey privateKey) 1479 throws InvalidKeyException { 1480 cipher.init(Cipher.ENCRYPT_MODE, privateKey); 1481 data = null; 1482 } 1483 1484 protected void engineInitSign(PrivateKey privateKey, 1485 SecureRandom random) throws InvalidKeyException { 1486 cipher.init(Cipher.ENCRYPT_MODE, privateKey, random); 1487 data = null; 1488 } 1489 1490 protected void engineUpdate(byte b) throws SignatureException { 1491 engineUpdate(new byte[] {b}, 0, 1); 1492 } 1493 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 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 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 1533 protected void engineSetParameter(String param, Object value) 1534 throws InvalidParameterException { 1535 throw new InvalidParameterException("Parameters not supported"); 1536 } 1537 1538 protected Object engineGetParameter(String param) 1539 throws InvalidParameterException { 1540 throw new InvalidParameterException("Parameters not supported"); 1541 } 1542 1543 } 1544 1545 }