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