| 1 7 8 package java.security; 9 10 import java.security.spec.AlgorithmParameterSpec ; 11 import java.util.*; 12 import java.util.concurrent.ConcurrentHashMap ; 13 import java.io.*; 14 import java.security.cert.Certificate ; 15 import java.security.cert.X509Certificate ; 16 17 import java.nio.ByteBuffer ; 18 19 import java.security.Provider.Service; 20 21 import javax.crypto.Cipher; 22 import javax.crypto.CipherSpi; 23 import javax.crypto.IllegalBlockSizeException; 24 import javax.crypto.BadPaddingException; 25 import javax.crypto.NoSuchPaddingException; 26 27 import sun.security.util.Debug; 28 import sun.security.jca.*; 29 import sun.security.jca.GetInstance.Instance; 30 31 110 111 public abstract class Signature extends SignatureSpi { 112 113 private static final Debug debug = 114 Debug.getInstance("jca", "Signature"); 115 116 121 private String algorithm; 122 123 Provider provider; 125 126 130 protected final static int UNINITIALIZED = 0; 131 132 136 protected final static int SIGN = 2; 137 138 142 protected final static int VERIFY = 3; 143 144 147 protected int state = UNINITIALIZED; 148 149 158 protected Signature(String algorithm) { 159 this.algorithm = algorithm; 160 } 161 162 private final static String RSA_SIGNATURE = "NONEwithRSA"; 164 165 private final static String RSA_CIPHER = "RSA/ECB/PKCS1Padding"; 167 168 private final static List<ServiceId> rsaIds = Arrays.asList( 170 new ServiceId[] { 171 new ServiceId("Signature", "NONEwithRSA"), 172 new ServiceId("Cipher", "RSA/ECB/PKCS1Padding"), 173 new ServiceId("Cipher", "RSA/ECB"), 174 new ServiceId("Cipher", "RSA//PKCS1Padding"), 175 new ServiceId("Cipher", "RSA"), 176 } 177 ); 178 179 198 public static Signature getInstance(String algorithm) 199 throws NoSuchAlgorithmException { 200 List list; 201 if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) { 202 list = GetInstance.getServices(rsaIds); 203 } else { 204 list = GetInstance.getServices("Signature", algorithm); 205 } 206 Iterator t = list.iterator(); 207 if (t.hasNext() == false) { 208 throw new NoSuchAlgorithmException  209 (algorithm + " Signature not available"); 210 } 211 NoSuchAlgorithmException failure; 213 do { 214 Service s = (Service)t.next(); 215 if (isSpi(s)) { 216 return new Delegate(s, t, algorithm); 217 } else { 218 try { 220 Instance instance = 221 GetInstance.getInstance(s, SignatureSpi .class); 222 return getInstance(instance, algorithm); 223 } catch (NoSuchAlgorithmException e) { 224 failure = e; 225 } 226 } 227 } while (t.hasNext()); 228 throw failure; 229 } 230 231 private static Signature getInstance(Instance instance, String algorithm) { 232 Signature sig; 233 if (instance.impl instanceof Signature ) { 234 sig = (Signature )instance.impl; 235 } else { 236 SignatureSpi spi = (SignatureSpi )instance.impl; 237 sig = new Delegate(spi, algorithm); 238 } 239 sig.provider = instance.provider; 240 return sig; 241 } 242 243 private final static Map <String ,Boolean > signatureInfo; 244 245 static { 246 signatureInfo = new ConcurrentHashMap <String ,Boolean >(); 247 Boolean TRUE = Boolean.TRUE; 248 signatureInfo.put("sun.security.provider.DSA$RawDSA", TRUE); 250 signatureInfo.put("sun.security.provider.DSA$SHA1withDSA", TRUE); 251 signatureInfo.put("sun.security.rsa.RSASignature$MD2withRSA", TRUE); 252 signatureInfo.put("sun.security.rsa.RSASignature$MD5withRSA", TRUE); 253 signatureInfo.put("sun.security.rsa.RSASignature$SHA1withRSA", TRUE); 254 signatureInfo.put("sun.security.rsa.RSASignature$SHA256withRSA", TRUE); 255 signatureInfo.put("sun.security.rsa.RSASignature$SHA384withRSA", TRUE); 256 signatureInfo.put("sun.security.rsa.RSASignature$SHA512withRSA", TRUE); 257 signatureInfo.put("com.sun.net.ssl.internal.ssl.RSASignature", TRUE); 258 signatureInfo.put("sun.security.pkcs11.P11Signature", TRUE); 259 } 260 261 private static boolean isSpi(Service s) { 262 if (s.getType().equals("Cipher")) { 263 return true; 265 } 266 String className = s.getClassName(); 267 Boolean result = signatureInfo.get(className); 268 if (result == null) { 269 try { 270 Object instance = s.newInstance(null); 271 boolean r = (instance instanceof SignatureSpi ) 275 && (instance instanceof Signature == false); 276 if ((debug != null) && (r == false)) { 277 debug.println("Not a SignatureSpi " + className); 278 debug.println("Delayed provider selection may not be " 279 + "available for algorithm " + s.getAlgorithm()); 280 } 281 result = Boolean.valueOf(r); 282 signatureInfo.put(className, result); 283 } catch (Exception e) { 284 return false; 286 } 287 } 288 return result.booleanValue(); 289 } 290 291 318 public static Signature getInstance(String algorithm, String provider) 319 throws NoSuchAlgorithmException , NoSuchProviderException { 320 if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) { 321 if ((provider == null) || (provider.length() == 0)) { 323 throw new IllegalArgumentException ("missing provider"); 324 } 325 Provider p = Security.getProvider(provider); 326 if (p == null) { 327 throw new NoSuchProviderException  328 ("no such provider: " + provider); 329 } 330 return getInstanceRSA(p); 331 } 332 Instance instance = GetInstance.getInstance 333 ("Signature", SignatureSpi .class, algorithm, provider); 334 return getInstance(instance, algorithm); 335 } 336 337 364 public static Signature getInstance(String algorithm, Provider provider) 365 throws NoSuchAlgorithmException { 366 if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) { 367 if (provider == null) { 369 throw new IllegalArgumentException ("missing provider"); 370 } 371 return getInstanceRSA(provider); 372 } 373 Instance instance = GetInstance.getInstance 374 ("Signature", SignatureSpi .class, algorithm, provider); 375 return getInstance(instance, algorithm); 376 } 377 378 private static Signature getInstanceRSA(Provider p) 381 throws NoSuchAlgorithmException { 382 Service s = p.getService("Signature", RSA_SIGNATURE); 384 if (s != null) { 385 Instance instance = GetInstance.getInstance(s, SignatureSpi .class); 386 return getInstance(instance, RSA_SIGNATURE); 387 } 388 try { 390 Cipher c = Cipher.getInstance(RSA_CIPHER, p); 391 return new Delegate(new CipherAdapter(c), RSA_SIGNATURE); 392 } catch (GeneralSecurityException e) { 393 throw new NoSuchAlgorithmException ("no such algorithm: " 396 + RSA_SIGNATURE + " for provider " + p.getName(), e); 397 } 398 } 399 400 405 public final Provider getProvider() { 406 chooseFirstProvider(); 407 return this.provider; 408 } 409 410 void chooseFirstProvider() { 411 } 413 414 424 public final void initVerify(PublicKey publicKey) 425 throws InvalidKeyException { 426 engineInitVerify(publicKey); 427 state = VERIFY; 428 } 429 430 447 public final void initVerify(Certificate certificate) 448 throws InvalidKeyException { 449 if (certificate instanceof java.security.cert.X509Certificate ) { 453 X509Certificate cert = (X509Certificate )certificate; 457 Set critSet = cert.getCriticalExtensionOIDs(); 458 459 if (critSet != null && !critSet.isEmpty() 460 && critSet.contains("2.5.29.15")) { 461 boolean[] keyUsageInfo = cert.getKeyUsage(); 462 if ((keyUsageInfo != null) && (keyUsageInfo[0] == false)) 464 throw new InvalidKeyException ("Wrong key usage"); 465 } 466 } 467 468 PublicKey publicKey = certificate.getPublicKey(); 469 engineInitVerify(publicKey); 470 state = VERIFY; 471 } 472 473 483 public final void initSign(PrivateKey privateKey) 484 throws InvalidKeyException { 485 engineInitSign(privateKey); 486 state = SIGN; 487 } 488 489 501 public final void initSign(PrivateKey privateKey, SecureRandom random) 502 throws InvalidKeyException { 503 engineInitSign(privateKey, random); 504 state = SIGN; 505 } 506 507 525 public final byte[] sign() throws SignatureException { 526 if (state == SIGN) { 527 return engineSign(); 528 } 529 throw new SignatureException ("object not initialized for " + 530 "signing"); 531 } 532 533 561 public final int sign(byte[] outbuf, int offset, int len) 562 throws SignatureException { 563 if (outbuf == null) { 564 throw new IllegalArgumentException ("No output buffer given"); 565 } 566 if (outbuf.length - offset < len) { 567 throw new IllegalArgumentException  568 ("Output buffer too small for specified offset and length"); 569 } 570 if (state != SIGN) { 571 throw new SignatureException ("object not initialized for " + 572 "signing"); 573 } 574 return engineSign(outbuf, offset, len); 575 } 576 577 595 public final boolean verify(byte[] signature) throws SignatureException { 596 if (state == VERIFY) { 597 return engineVerify(signature); 598 } 599 throw new SignatureException ("object not initialized for " + 600 "verification"); 601 } 602 603 630 public final boolean verify(byte[] signature, int offset, int length) 631 throws SignatureException { 632 if (state == VERIFY) { 633 if ((signature == null) || (offset < 0) || (length < 0) || 634 (offset + length > signature.length)) { 635 throw new IllegalArgumentException ("Bad arguments"); 636 } 637 638 return engineVerify(signature, offset, length); 639 } 640 throw new SignatureException ("object not initialized for " + 641 "verification"); 642 } 643 644 652 public final void update(byte b) throws SignatureException { 653 if (state == VERIFY || state == SIGN) { 654 engineUpdate(b); 655 } else { 656 throw new SignatureException ("object not initialized for " 657 + "signature or verification"); 658 } 659 } 660 661 670 public final void update(byte[] data) throws SignatureException { 671 update(data, 0, data.length); 672 } 673 674 685 public final void update(byte[] data, int off, int len) 686 throws SignatureException { 687 if (state == SIGN || state == VERIFY) { 688 engineUpdate(data, off, len); 689 } else { 690 throw new SignatureException ("object not initialized for " 691 + "signature or verification"); 692 } 693 } 694 695 708 public final void update(ByteBuffer data) throws SignatureException { 709 if ((state != SIGN) && (state != VERIFY)) { 710 throw new SignatureException ("object not initialized for " 711 + "signature or verification"); 712 } 713 if (data == null) { 714 throw new NullPointerException (); 715 } 716 engineUpdate(data); 717 } 718 719 724 public final String getAlgorithm() { 725 return this.algorithm; 726 } 727 728 735 public String toString() { 736 String initState = ""; 737 switch (state) { 738 case UNINITIALIZED: 739 initState = "<not initialized>"; 740 break; 741 case VERIFY: 742 initState = "<initialized for verifying>"; 743 break; 744 case SIGN: 745 initState = "<initialized for signing>"; 746 break; 747 } 748 return "Signature object: " + getAlgorithm() + initState; 749 } 750 751 776 @Deprecated  777 public final void setParameter(String param, Object value) 778 throws InvalidParameterException { 779 engineSetParameter(param, value); 780 } 781 782 792 public final void setParameter(AlgorithmParameterSpec params) 793 throws InvalidAlgorithmParameterException { 794 engineSetParameter(params); 795 } 796 797 811 public final AlgorithmParameters getParameters() { 812 return engineGetParameters(); 813 } 814 815 838 @Deprecated  839 public final Object getParameter(String param) 840 throws InvalidParameterException { 841 return engineGetParameter(param); 842 } 843 844 852 public Object clone() throws CloneNotSupportedException { 853 if (this instanceof Cloneable ) { 854 return super.clone(); 855 } else { 856 throw new CloneNotSupportedException (); 857 } 858 } 859 860 873 874 private static class Delegate extends Signature { 875 876 private SignatureSpi sigSpi; 879 880 private final Object lock; 882 883 private Service firstService; 886 887 private Iterator serviceIterator; 890 891 Delegate(SignatureSpi sigSpi, String algorithm) { 893 super(algorithm); 894 this.sigSpi = sigSpi; 895 this.lock = null; } 897 898 Delegate(Service service, Iterator iterator, String algorithm) { 900 super(algorithm); 901 this.firstService = service; 902 this.serviceIterator = iterator; 903 this.lock = new Object (); 904 } 905 906 |