0001 /*
0002 * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025
0026 package java.security;
0027
0028 import java.security.spec.AlgorithmParameterSpec;
0029 import java.util.*;
0030 import java.util.concurrent.ConcurrentHashMap;
0031 import java.io.*;
0032 import java.security.cert.Certificate;
0033 import java.security.cert.X509Certificate;
0034
0035 import java.nio.ByteBuffer;
0036
0037 import java.security.Provider.Service;
0038
0039 import javax.crypto.Cipher;
0040 import javax.crypto.CipherSpi;
0041 import javax.crypto.IllegalBlockSizeException;
0042 import javax.crypto.BadPaddingException;
0043 import javax.crypto.NoSuchPaddingException;
0044
0045 import sun.security.util.Debug;
0046 import sun.security.jca.*;
0047 import sun.security.jca.GetInstance.Instance;
0048
0049 /**
0050 * This Signature class is used to provide applications the functionality
0051 * of a digital signature algorithm. Digital signatures are used for
0052 * authentication and integrity assurance of digital data.
0053 *
0054 * <p> The signature algorithm can be, among others, the NIST standard
0055 * DSA, using DSA and SHA-1. The DSA algorithm using the
0056 * SHA-1 message digest algorithm can be specified as <tt>SHA1withDSA</tt>.
0057 * In the case of RSA, there are multiple choices for the message digest
0058 * algorithm, so the signing algorithm could be specified as, for example,
0059 * <tt>MD2withRSA</tt>, <tt>MD5withRSA</tt>, or <tt>SHA1withRSA</tt>.
0060 * The algorithm name must be specified, as there is no default.
0061 *
0062 * <p> A Signature object can be used to generate and verify digital
0063 * signatures.
0064 *
0065 * <p> There are three phases to the use of a Signature object for
0066 * either signing data or verifying a signature:<ol>
0067 *
0068 * <li>Initialization, with either
0069 *
0070 * <ul>
0071 *
0072 * <li>a public key, which initializes the signature for
0073 * verification (see {@link #initVerify(PublicKey) initVerify}), or
0074 *
0075 * <li>a private key (and optionally a Secure Random Number Generator),
0076 * which initializes the signature for signing
0077 * (see {@link #initSign(PrivateKey)}
0078 * and {@link #initSign(PrivateKey, SecureRandom)}).
0079 *
0080 * </ul><p>
0081 *
0082 * <li>Updating<p>
0083 *
0084 * <p>Depending on the type of initialization, this will update the
0085 * bytes to be signed or verified. See the
0086 * {@link #update(byte) update} methods.<p>
0087 *
0088 * <li>Signing or Verifying a signature on all updated bytes. See the
0089 * {@link #sign() sign} methods and the {@link #verify(byte[]) verify}
0090 * method.
0091 *
0092 * </ol>
0093 *
0094 * <p>Note that this class is abstract and extends from
0095 * <code>SignatureSpi</code> for historical reasons.
0096 * Application developers should only take notice of the methods defined in
0097 * this <code>Signature</code> class; all the methods in
0098 * the superclass are intended for cryptographic service providers who wish to
0099 * supply their own implementations of digital signature algorithms.
0100 *
0101 * @author Benjamin Renaud
0102 *
0103 * @version 1.110, 05/05/07
0104 */
0105
0106 public abstract class Signature extends SignatureSpi {
0107
0108 private static final Debug debug = Debug.getInstance("jca",
0109 "Signature");
0110
0111 /*
0112 * The algorithm for this signature object.
0113 * This value is used to map an OID to the particular algorithm.
0114 * The mapping is done in AlgorithmObject.algOID(String algorithm)
0115 */
0116 private String algorithm;
0117
0118 // The provider
0119 Provider provider;
0120
0121 /**
0122 * Possible {@link #state} value, signifying that
0123 * this signature object has not yet been initialized.
0124 */
0125 protected final static int UNINITIALIZED = 0;
0126
0127 /**
0128 * Possible {@link #state} value, signifying that
0129 * this signature object has been initialized for signing.
0130 */
0131 protected final static int SIGN = 2;
0132
0133 /**
0134 * Possible {@link #state} value, signifying that
0135 * this signature object has been initialized for verification.
0136 */
0137 protected final static int VERIFY = 3;
0138
0139 /**
0140 * Current state of this signature object.
0141 */
0142 protected int state = UNINITIALIZED;
0143
0144 /**
0145 * Creates a Signature object for the specified algorithm.
0146 *
0147 * @param algorithm the standard string name of the algorithm.
0148 * See Appendix A in the <a href=
0149 * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
0150 * Java Cryptography Architecture API Specification & Reference </a>
0151 * for information about standard algorithm names.
0152 */
0153 protected Signature(String algorithm) {
0154 this .algorithm = algorithm;
0155 }
0156
0157 // name of the special signature alg
0158 private final static String RSA_SIGNATURE = "NONEwithRSA";
0159
0160 // name of the equivalent cipher alg
0161 private final static String RSA_CIPHER = "RSA/ECB/PKCS1Padding";
0162
0163 // all the services we need to lookup for compatibility with Cipher
0164 private final static List<ServiceId> rsaIds = Arrays
0165 .asList(new ServiceId[] {
0166 new ServiceId("Signature", "NONEwithRSA"),
0167 new ServiceId("Cipher", "RSA/ECB/PKCS1Padding"),
0168 new ServiceId("Cipher", "RSA/ECB"),
0169 new ServiceId("Cipher", "RSA//PKCS1Padding"),
0170 new ServiceId("Cipher", "RSA"), });
0171
0172 /**
0173 * Returns a Signature object that implements the specified signature
0174 * algorithm.
0175 *
0176 * <p> This method traverses the list of registered security Providers,
0177 * starting with the most preferred Provider.
0178 * A new Signature object encapsulating the
0179 * SignatureSpi implementation from the first
0180 * Provider that supports the specified algorithm is returned.
0181 *
0182 * <p> Note that the list of registered providers may be retrieved via
0183 * the {@link Security#getProviders() Security.getProviders()} method.
0184 *
0185 * @param algorithm the standard name of the algorithm requested.
0186 * See Appendix A in the <a href=
0187 * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
0188 * Java Cryptography Architecture API Specification & Reference </a>
0189 * for information about standard algorithm names.
0190 *
0191 * @return the new Signature object.
0192 *
0193 * @exception NoSuchAlgorithmException if no Provider supports a
0194 * Signature implementation for the
0195 * specified algorithm.
0196 *
0197 * @see Provider
0198 */
0199 public static Signature getInstance(String algorithm)
0200 throws NoSuchAlgorithmException {
0201 List<Service> list;
0202 if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
0203 list = GetInstance.getServices(rsaIds);
0204 } else {
0205 list = GetInstance.getServices("Signature", algorithm);
0206 }
0207 Iterator<Service> t = list.iterator();
0208 if (t.hasNext() == false) {
0209 throw new NoSuchAlgorithmException(algorithm
0210 + " Signature not available");
0211 }
0212 // try services until we find an Spi or a working Signature subclass
0213 NoSuchAlgorithmException failure;
0214 do {
0215 Service s = t.next();
0216 if (isSpi(s)) {
0217 return new Delegate(s, t, algorithm);
0218 } else {
0219 // must be a subclass of Signature, disable dynamic selection
0220 try {
0221 Instance instance = GetInstance.getInstance(s,
0222 SignatureSpi.class);
0223 return getInstance(instance, algorithm);
0224 } catch (NoSuchAlgorithmException e) {
0225 failure = e;
0226 }
0227 }
0228 } while (t.hasNext());
0229 throw failure;
0230 }
0231
0232 private static Signature getInstance(Instance instance,
0233 String algorithm) {
0234 Signature sig;
0235 if (instance.impl instanceof Signature) {
0236 sig = (Signature) instance.impl;
0237 } else {
0238 SignatureSpi spi = (SignatureSpi) instance.impl;
0239 sig = new Delegate(spi, algorithm);
0240 }
0241 sig.provider = instance.provider;
0242 return sig;
0243 }
0244
0245 private final static Map<String, Boolean> signatureInfo;
0246
0247 static {
0248 signatureInfo = new ConcurrentHashMap<String, Boolean>();
0249 Boolean TRUE = Boolean.TRUE;
0250 // pre-initialize with values for our SignatureSpi implementations
0251 signatureInfo.put("sun.security.provider.DSA$RawDSA", TRUE);
0252 signatureInfo
0253 .put("sun.security.provider.DSA$SHA1withDSA", TRUE);
0254 signatureInfo.put("sun.security.rsa.RSASignature$MD2withRSA",
0255 TRUE);
0256 signatureInfo.put("sun.security.rsa.RSASignature$MD5withRSA",
0257 TRUE);
0258 signatureInfo.put("sun.security.rsa.RSASignature$SHA1withRSA",
0259 TRUE);
0260 signatureInfo.put(
0261 "sun.security.rsa.RSASignature$SHA256withRSA", TRUE);
0262 signatureInfo.put(
0263 "sun.security.rsa.RSASignature$SHA384withRSA", TRUE);
0264 signatureInfo.put(
0265 "sun.security.rsa.RSASignature$SHA512withRSA", TRUE);
0266 signatureInfo.put("com.sun.net.ssl.internal.ssl.RSASignature",
0267 TRUE);
0268 signatureInfo.put("sun.security.pkcs11.P11Signature", TRUE);
0269 }
0270
0271 private static boolean isSpi(Service s) {
0272 if (s.getType().equals("Cipher")) {
0273 // must be a CipherSpi, which we can wrap with the CipherAdapter
0274 return true;
0275 }
0276 String className = s.getClassName();
0277 Boolean result = signatureInfo.get(className);
0278 if (result == null) {
0279 try {
0280 Object instance = s.newInstance(null);
0281 // Signature extends SignatureSpi
0282 // so it is a "real" Spi if it is an
0283 // instance of SignatureSpi but not Signature
0284 boolean r = (instance instanceof SignatureSpi)
0285 && (instance instanceof Signature == false);
0286 if ((debug != null) && (r == false)) {
0287 debug.println("Not a SignatureSpi " + className);
0288 debug
0289 .println("Delayed provider selection may not be "
0290 + "available for algorithm "
0291 + s.getAlgorithm());
0292 }
0293 result = Boolean.valueOf(r);
0294 signatureInfo.put(className, result);
0295 } catch (Exception e) {
0296 // something is wrong, assume not an SPI
0297 return false;
0298 }
0299 }
0300 return result.booleanValue();
0301 }
0302
0303 /**
0304 * Returns a Signature object that implements the specified signature
0305 * algorithm.
0306 *
0307 * <p> A new Signature object encapsulating the
0308 * SignatureSpi implementation from the specified provider
0309 * is returned. The specified provider must be registered
0310 * in the security provider list.
0311 *
0312 * <p> Note that the list of registered providers may be retrieved via
0313 * the {@link Security#getProviders() Security.getProviders()} method.
0314 *
0315 * @param algorithm the name of the algorithm requested.
0316 * See Appendix A in the <a href=
0317 * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
0318 * Java Cryptography Architecture API Specification & Reference </a>
0319 * for information about standard algorithm names.
0320 *
0321 * @param provider the name of the provider.
0322 *
0323 * @return the new Signature object.
0324 *
0325 * @exception NoSuchAlgorithmException if a SignatureSpi
0326 * implementation for the specified algorithm is not
0327 * available from the specified provider.
0328 *
0329 * @exception NoSuchProviderException if the specified provider is not
0330 * registered in the security provider list.
0331 *
0332 * @exception IllegalArgumentException if the provider name is null
0333 * or empty.
0334 *
0335 * @see Provider
0336 */
0337 public static Signature getInstance(String algorithm,
0338 String provider) throws NoSuchAlgorithmException,
0339 NoSuchProviderException {
0340 if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
0341 // exception compatibility with existing code
0342 if ((provider == null) || (provider.length() == 0)) {
0343 throw new IllegalArgumentException("missing provider");
0344 }
0345 Provider p = Security.getProvider(provider);
0346 if (p == null) {
0347 throw new NoSuchProviderException("no such provider: "
0348 + provider);
0349 }
0350 return getInstanceRSA(p);
0351 }
0352 Instance instance = GetInstance.getInstance("Signature",
0353 SignatureSpi.class, algorithm, provider);
0354 return getInstance(instance, algorithm);
0355 }
0356
0357 /**
0358 * Returns a Signature object that implements the specified
0359 * signature algorithm.
0360 *
0361 * <p> A new Signature object encapsulating the
0362 * SignatureSpi implementation from the specified Provider
0363 * object is returned. Note that the specified Provider object
0364 * does not have to be registered in the provider list.
0365 *
0366 * @param algorithm the name of the algorithm requested.
0367 * See Appendix A in the <a href=
0368 * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
0369 * Java Cryptography Architecture API Specification & Reference </a>
0370 * for information about standard algorithm names.
0371 *
0372 * @param provider the provider.
0373 *
0374 * @return the new Signature object.
0375 *
0376 * @exception NoSuchAlgorithmException if a SignatureSpi
0377 * implementation for the specified algorithm is not available
0378 * from the specified Provider object.
0379 *
0380 * @exception IllegalArgumentException if the provider is null.
0381 *
0382 * @see Provider
0383 *
0384 * @since 1.4
0385 */
0386 public static Signature getInstance(String algorithm,
0387 Provider provider) throws NoSuchAlgorithmException {
0388 if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
0389 // exception compatibility with existing code
0390 if (provider == null) {
0391 throw new IllegalArgumentException("missing provider");
0392 }
0393 return getInstanceRSA(provider);
0394 }
0395 Instance instance = GetInstance.getInstance("Signature",
0396 SignatureSpi.class, algorithm, provider);
0397 return getInstance(instance, algorithm);
0398 }
0399
0400 // return an implementation for NONEwithRSA, which is a special case
0401 // because of the Cipher.RSA/ECB/PKCS1Padding compatibility wrapper
0402 private static Signature getInstanceRSA(Provider p)
0403 throws NoSuchAlgorithmException {
0404 // try Signature first
0405 Service s = p.getService("Signature", RSA_SIGNATURE);
0406 if (s != null) {
0407 Instance instance = GetInstance.getInstance(s,
0408 SignatureSpi.class);
0409 return getInstance(instance, RSA_SIGNATURE);
0410 }
0411 // check Cipher
0412 try {
0413 Cipher c = Cipher.getInstance(RSA_CIPHER, p);
0414 return new Delegate(new CipherAdapter(c), RSA_SIGNATURE);
0415 } catch (GeneralSecurityException e) {
0416 // throw Signature style exception message to avoid confusion,
0417 // but append Cipher exception as cause
0418 throw new NoSuchAlgorithmException("no such algorithm: "
0419 + RSA_SIGNATURE + " for provider " + p.getName(), e);
0420 }
0421 }
0422
0423 /**
0424 * Returns the provider of this signature object.
0425 *
0426 * @return the provider of this signature object
0427 */
0428 public final Provider getProvider() {
0429 chooseFirstProvider();
0430 return this .provider;
0431 }
0432
0433 void chooseFirstProvider() {
0434 // empty, overridden in Delegate
0435 }
0436
0437 /**
0438 * Initializes this object for verification. If this method is called
0439 * again with a different argument, it negates the effect
0440 * of this call.
0441 *
0442 * @param publicKey the public key of the identity whose signature is
0443 * going to be verified.
0444 *
0445 * @exception InvalidKeyException if the key is invalid.
0446 */
0447 public final void initVerify(PublicKey publicKey)
0448 throws InvalidKeyException {
0449 engineInitVerify(publicKey);
0450 state = VERIFY;
0451 }
0452
0453 /**
0454 * Initializes this object for verification, using the public key from
0455 * the given certificate.
0456 * <p>If the certificate is of type X.509 and has a <i>key usage</i>
0457 * extension field marked as critical, and the value of the <i>key usage</i>
0458 * extension field implies that the public key in
0459 * the certificate and its corresponding private key are not
0460 * supposed to be used for digital signatures, an
0461 * <code>InvalidKeyException</code> is thrown.
0462 *
0463 * @param certificate the certificate of the identity whose signature is
0464 * going to be verified.
0465 *
0466 * @exception InvalidKeyException if the public key in the certificate
0467 * is not encoded properly or does not include required parameter
0468 * information or cannot be used for digital signature purposes.
0469 * @since 1.3
0470 */
0471 public final void initVerify(Certificate certificate)
0472 throws InvalidKeyException {
0473 // If the certificate is of type X509Certificate,
0474 // we should check whether it has a Key Usage
0475 // extension marked as critical.
0476 if (certificate instanceof java.security.cert.X509Certificate) {
0477 // Check whether the cert has a key usage extension
0478 // marked as a critical extension.
0479 // The OID for KeyUsage extension is 2.5.29.15.
0480 X509Certificate cert = (X509Certificate) certificate;
0481 Set<String> critSet = cert.getCriticalExtensionOIDs();
0482
0483 if (critSet != null && !critSet.isEmpty()
0484 && critSet.contains("2.5.29.15")) {
0485 boolean[] keyUsageInfo = cert.getKeyUsage();
0486 // keyUsageInfo[0] is for digitalSignature.
0487 if ((keyUsageInfo != null)
0488 && (keyUsageInfo[0] == false))
0489 throw new InvalidKeyException("Wrong key usage");
0490 }
0491 }
0492
0493 PublicKey publicKey = certificate.getPublicKey();
0494 engineInitVerify(publicKey);
0495 state = VERIFY;
0496 }
0497
0498 /**
0499 * Initialize this object for signing. If this method is called
0500 * again with a different argument, it negates the effect
0501 * of this call.
0502 *
0503 * @param privateKey the private key of the identity whose signature
0504 * is going to be generated.
0505 *
0506 * @exception InvalidKeyException if the key is invalid.
0507 */
0508 public final void initSign(PrivateKey privateKey)
0509 throws InvalidKeyException {
0510 engineInitSign(privateKey);
0511 state = SIGN;
0512 }
0513
0514 /**
0515 * Initialize this object for signing. If this method is called
0516 * again with a different argument, it negates the effect
0517 * of this call.
0518 *
0519 * @param privateKey the private key of the identity whose signature
0520 * is going to be generated.
0521 *
0522 * @param random the source of randomness for this signature.
0523 *
0524 * @exception InvalidKeyException if the key is invalid.
0525 */
0526 public final void initSign(PrivateKey privateKey,
0527 SecureRandom random) throws InvalidKeyException {
0528 engineInitSign(privateKey, random);
0529 state = SIGN;
0530 }
0531
0532 /**
0533 * Returns the signature bytes of all the data updated.
0534 * The format of the signature depends on the underlying
0535 * signature scheme.
0536 *
0537 * <p>A call to this method resets this signature object to the state
0538 * it was in when previously initialized for signing via a
0539 * call to <code>initSign(PrivateKey)</code>. That is, the object is
0540 * reset and available to generate another signature from the same
0541 * signer, if desired, via new calls to <code>update</code> and
0542 * <code>sign</code>.
0543 *
0544 * @return the signature bytes of the signing operation's result.
0545 *
0546 * @exception SignatureException if this signature object is not
0547 * initialized properly or if this signature algorithm is unable to
0548 * process the input data provided.
0549 */
0550 public final byte[] sign() throws SignatureException {
0551 if (state == SIGN) {
0552 return engineSign();
0553 }
0554 throw new SignatureException("object not initialized for "
0555 + "signing");
0556 }
0557
0558 /**
0559 * Finishes the signature operation and stores the resulting signature
0560 * bytes in the provided buffer <code>outbuf</code>, starting at
0561 * <code>offset</code>.
0562 * The format of the signature depends on the underlying
0563 * signature scheme.
0564 *
0565 * <p>This signature object is reset to its initial state (the state it
0566 * was in after a call to one of the <code>initSign</code> methods) and
0567 * can be reused to generate further signatures with the same private key.
0568 *
0569 * @param outbuf buffer for the signature result.
0570 *
0571 * @param offset offset into <code>outbuf</code> where the signature is
0572 * stored.
0573 *
0574 * @param len number of bytes within <code>outbuf</code> allotted for the
0575 * signature.
0576 *
0577 * @return the number of bytes placed into <code>outbuf</code>.
0578 *
0579 * @exception SignatureException if this signature object is not
0580 * initialized properly, if this signature algorithm is unable to
0581 * process the input data provided, or if <code>len</code> is less
0582 * than the actual signature length.
0583 *
0584 * @since 1.2
0585 */
0586 public final int sign(byte[] outbuf, int offset, int len)
0587 throws SignatureException {
0588 if (outbuf == null) {
0589 throw new IllegalArgumentException("No output buffer given");
0590 }
0591 if (outbuf.length - offset < len) {
0592 throw new IllegalArgumentException(
0593 "Output buffer too small for specified offset and length");
0594 }
0595 if (state != SIGN) {
0596 throw new SignatureException("object not initialized for "
0597 + "signing");
0598 }
0599 return engineSign(outbuf, offset, len);
0600 }
0601
0602 /**
0603 * Verifies the passed-in signature.
0604 *
0605 * <p>A call to this method resets this signature object to the state
0606 * it was in when previously initialized for verification via a
0607 * call to <code>initVerify(PublicKey)</code>. That is, the object is
0608 * reset and available to verify another signature from the identity
0609 * whose public key was specified in the call to <code>initVerify</code>.
0610 *
0611 * @param signature the signature bytes to be verified.
0612 *
0613 * @return true if the signature was verified, false if not.
0614 *
0615 * @exception SignatureException if this signature object is not
0616 * initialized properly, the passed-in signature is improperly
0617 * encoded or of the wrong type, if this signature algorithm is unable to
0618 * process the input data provided, etc.
0619 */
0620 public final boolean verify(byte[] signature)
0621 throws SignatureException {
0622 if (state == VERIFY) {
0623 return engineVerify(signature);
0624 }
0625 throw new SignatureException("object not initialized for "
0626 + "verification");
0627 }
0628
0629 /**
0630 * Verifies the passed-in signature in the specified array
0631 * of bytes, starting at the specified offset.
0632 *
0633 * <p>A call to this method resets this signature object to the state
0634 * it was in when previously initialized for verification via a
0635 * call to <code>initVerify(PublicKey)</code>. That is, the object is
0636 * reset and available to verify another signature from the identity
0637 * whose public key was specified in the call to <code>initVerify</code>.
0638 *
0639 *
0640 * @param signature the signature bytes to be verified.
0641 * @param offset the offset to start from in the array of bytes.
0642 * @param length the number of bytes to use, starting at offset.
0643 *
0644 * @return true if the signature was verified, false if not.
0645 *
0646 * @exception SignatureException if this signature object is not
0647 * initialized properly, the passed-in signature is improperly
0648 * encoded or of the wrong type, if this signature algorithm is unable to
0649 * process the input data provided, etc.
0650 * @exception IllegalArgumentException if the <code>signature</code>
0651 * byte array is null, or the <code>offset</code> or <code>length</code>
0652 * is less than 0, or the sum of the <code>offset</code> and
0653 * <code>length</code> is greater than the length of the
0654 * <code>signature</code> byte array.
0655 * @since 1.4
0656 */
0657 public final boolean verify(byte[] signature, int offset, int length)
0658 throws SignatureException {
0659 if (state == VERIFY) {
0660 if ((signature == null) || (offset < 0) || (length < 0)
0661 || (offset + length > signature.length)) {
0662 throw new IllegalArgumentException("Bad arguments");
0663 }
0664
0665 return engineVerify(signature, offset, length);
0666 }
0667 throw new SignatureException("object not initialized for "
0668 + "verification");
0669 }
0670
0671 /**
0672 * Updates the data to be signed or verified by a byte.
0673 *
0674 * @param b the byte to use for the update.
0675 *
0676 * @exception SignatureException if this signature object is not
0677 * initialized properly.
0678 */
0679 public final void update(byte b) throws SignatureException {
0680 if (state == VERIFY || state == SIGN) {
0681 engineUpdate(b);
0682 } else {
0683 throw new SignatureException("object not initialized for "
0684 + "signature or verification");
0685 }
0686 }
0687
0688 /**
0689 * Updates the data to be signed or verified, using the specified
0690 * array of bytes.
0691 *
0692 * @param data the byte array to use for the update.
0693 *
0694 * @exception SignatureException if this signature object is not
0695 * initialized properly.
0696 */
0697 public final void update(byte[] data) throws SignatureException {
0698 update(data, 0, data.length);
0699 }
0700
0701 /**
0702 * Updates the data to be signed or verified, using the specified
0703 * array of bytes, starting at the specified offset.
0704 *
0705 * @param data the array of bytes.
0706 * @param off the offset to start from in the array of bytes.
0707 * @param len the number of bytes to use, starting at offset.
0708 *
0709 * @exception SignatureException if this signature object is not
0710 * initialized properly.
0711 */
0712 public final void update(byte[] data, int off, int len)
0713 throws SignatureException {
0714 if (state == SIGN || state == VERIFY) {
0715 engineUpdate(data, off, len);
0716 } else {
0717 throw new SignatureException("object not initialized for "
0718 + "signature or verification");
0719 }
0720 }
0721
0722 /**
0723 * Updates the data to be signed or verified using the specified
0724 * ByteBuffer. Processes the <code>data.remaining()</code> bytes
0725 * starting at at <code>data.position()</code>.
0726 * Upon return, the buffer's position will be equal to its limit;
0727 * its limit will not have changed.
0728 *
0729 * @param data the ByteBuffer
0730 *
0731 * @exception SignatureException if this signature object is not
0732 * initialized properly.
0733 * @since 1.5
0734 */
0735 public final void update(ByteBuffer data) throws SignatureException {
0736 if ((state != SIGN) && (state != VERIFY)) {
0737 throw new SignatureException("object not initialized for "
0738 + "signature or verification");
0739 }
0740 if (data == null) {
0741 throw new NullPointerException();
0742 }
0743 engineUpdate(data);
0744 }
0745
0746 /**
0747 * Returns the name of the algorithm for this signature object.
0748 *
0749 * @return the name of the algorithm for this signature object.
0750 */
0751 public final String getAlgorithm() {
0752 return this .algorithm;
0753 }
0754
0755 /**
0756 * Returns a string representation of this signature object,
0757 * providing information that includes the state of the object
0758 * and the name of the algorithm used.
0759 *
0760 * @return a string representation of this signature object.
0761 */
0762 public String toString() {
0763 String initState = "";
0764 switch (state) {
0765 case UNINITIALIZED:
0766 initState = "<not initialized>";
0767 break;
0768 case VERIFY:
0769 initState = "<initialized for verifying>";
0770 break;
0771 case SIGN:
0772 initState = "<initialized for signing>";
0773 break;
0774 }
0775 return "Signature object: " + getAlgorithm() + initState;
0776 }
0777
0778 /**
0779 * Sets the specified algorithm parameter to the specified value.
0780 * This method supplies a general-purpose mechanism through
0781 * which it is possible to set the various parameters of this object.
0782 * A parameter may be any settable parameter for the algorithm, such as
0783 * a parameter size, or a source of random bits for signature generation
0784 * (if appropriate), or an indication of whether or not to perform
0785 * a specific but optional computation. A uniform algorithm-specific
0786 * naming scheme for each parameter is desirable but left unspecified
0787 * at this time.
0788 *
0789 * @param param the string identifier of the parameter.
0790 * @param value the parameter value.
0791 *
0792 * @exception InvalidParameterException if <code>param</code> is an
0793 * invalid parameter for this signature algorithm engine,
0794 * the parameter is already set
0795 * and cannot be set again, a security exception occurs, and so on.
0796 *
0797 * @see #getParameter
0798 *
0799 * @deprecated Use
0800 * {@link #setParameter(java.security.spec.AlgorithmParameterSpec)
0801 * setParameter}.
0802 */
0803 @Deprecated
0804 public final void setParameter(String param, Object value)
0805 throws InvalidParameterException {
0806 engineSetParameter(param, value);
0807 }
0808
0809 /**
0810 * Initializes this signature engine with the specified parameter set.
0811 *
0812 * @param params the parameters
0813 *
0814 * @exception InvalidAlgorithmParameterException if the given parameters
0815 * are inappropriate for this signature engine
0816 *
0817 * @see #getParameters
0818 */
0819 public final void setParameter(AlgorithmParameterSpec params)
0820 throws InvalidAlgorithmParameterException {
0821 engineSetParameter(params);
0822 }
0823
0824 /**
0825 * Returns the parameters used with this signature object.
0826 *
0827 * <p>The returned parameters may be the same that were used to initialize
0828 * this signature, or may contain a combination of default and randomly
0829 * generated parameter values used by the underlying signature
0830 * implementation if this signature requires algorithm parameters but
0831 * was not initialized with any.
0832 *
0833 * @return the parameters used with this signature, or null if this
0834 * signature does not use any parameters.
0835 *
0836 * @see #setParameter(AlgorithmParameterSpec)
0837 * @since 1.4
0838 */
0839 public final AlgorithmParameters getParameters() {
0840 return engineGetParameters();
0841 }
0842
0843 /**
0844 * Gets the value of the specified algorithm parameter. This method
0845 * supplies a general-purpose mechanism through which it is possible to
0846 * get the various parameters of this object. A parameter may be any
0847 * settable parameter for the algorithm, such as a parameter size, or
0848 * a source of random bits for signature generation (if appropriate),
0849 * or an indication of whether or not to perform a specific but optional
0850 * computation. A uniform algorithm-specific naming scheme for each
0851 * parameter is desirable but left unspecified at this time.
0852 *
0853 * @param param the string name of the parameter.
0854 *
0855 * @return the object that represents the parameter value, or null if
0856 * there is none.
0857 *
0858 * @exception InvalidParameterException if <code>param</code> is an invalid
0859 * parameter for this engine, or another exception occurs while
0860 * trying to get this parameter.
0861 *
0862 * @see #setParameter(String, Object)
0863 *
0864 * @deprecated
0865 */
0866 @Deprecated
0867 public final Object getParameter(String param)
0868 throws InvalidParameterException {
0869 return engineGetParameter(param);
0870 }
0871
0872 /**
0873 * Returns a clone if the implementation is cloneable.
0874 *
0875 * @return a clone if the implementation is cloneable.
0876 *
0877 * @exception CloneNotSupportedException if this is called
0878 * on an implementation that does not support <code>Cloneable</code>.
0879 */
0880 public Object clone() throws CloneNotSupportedException {
0881 if (this instanceof Cloneable) {
0882 return super .clone();
0883 } else {
0884 throw new CloneNotSupportedException();
0885 }
0886 }
0887
0888 /*
0889 * The following class allows providers to extend from SignatureSpi
0890 * rather than from Signature. It represents a Signature with an
0891 * encapsulated, provider-supplied SPI object (of type SignatureSpi).
0892 * If the provider implementation is an instance of SignatureSpi, the
0893 * getInstance() methods above return an instance of this class, with
0894 * the SPI object encapsulated.
0895 *
0896 * Note: All SPI methods from the original Signature class have been
0897 * moved up the hierarchy into a new class (SignatureSpi), which has
0898 * been interposed in the hierarchy between the API (Signature)
0899 * and its original parent (Object).
0900 */
0901
0902 private static class Delegate extends Signature {
0903
0904 // The provider implementation (delegate)
0905 // filled in once the provider is selected
0906 private SignatureSpi sigSpi;
0907
0908 // lock for mutex during provider selection
0909 private final Object lock;
0910
0911 // next service to try in provider selection
0912 // null once provider is selected
0913 private Service firstService;
0914
0915 // remaining services to try in provider selection
0916 // null once provider is selected
0917 private Iterator<Service> serviceIterator;
0918
0919 // constructor
0920 Delegate(SignatureSpi sigSpi, String algorithm) {
0921 super (algorithm);
0922 this .sigSpi = sigSpi;
0923 this .lock = null; // no lock needed
0924 }
0925
0926 // used with delayed provider selection
0927 Delegate(Service service, Iterator<Service> iterator,
0928 String algorithm) {
0929 super (algorithm);
0930 this .firstService = service;
0931 this .serviceIterator = iterator;
0932 this .lock = new Object();
0933 }
0934
0935 /**
0936 * Returns a clone if the delegate is cloneable.
0937 *
0938 * @return a clone if the delegate is cloneable.
0939 *
0940 * @exception CloneNotSupportedException if this is called on a
0941 * delegate that does not support <code>Cloneable</code>.
0942 */
0943 public Object clone() throws CloneNotSupportedException {
0944 chooseFirstProvider();
0945 if (sigSpi instanceof Cloneable) {
0946 SignatureSpi sigSpiClone = (SignatureSpi) sigSpi
0947 .clone();
0948 // Because 'algorithm' and 'provider' are private
0949 // members of our supertype, we must perform a cast to
0950 // access them.
0951 Signature that = new Delegate(sigSpiClone,
0952 ((Signature) this ).algorithm);
0953 that.provider = ((Signature) this ).provider;
0954 return that;
0955 } else {
0956 throw new CloneNotSupportedException();
0957 }
0958 }
0959
0960 private static SignatureSpi newInstance(Service s)
0961 throws NoSuchAlgorithmException {
0962 if (s.getType().equals("Cipher")) {
0963 // must be NONEwithRSA
0964 try {
0965 Cipher c = Cipher.getInstance(RSA_CIPHER, s
0966 .getProvider());
0967 return new CipherAdapter(c);
0968 } catch (NoSuchPaddingException e) {
0969 throw new NoSuchAlgorithmException(e);
0970 }
0971 } else {
0972 Object o = s.newInstance(null);
0973 if (o instanceof SignatureSpi == false) {
0974 throw new NoSuchAlgorithmException(
0975 "Not a SignatureSpi: "
0976 + o.getClass().getName());
0977 }
0978 return (SignatureSpi) o;
0979 }
0980 }
0981
0982 // max number of debug warnings to print from chooseFirstProvider()
0983 private static int warnCount = 10;
0984
0985 /**
0986 * Choose the Spi from the first provider available. Used if
0987 * delayed provider selection is not possible because initSign()/
0988 * initVerify() is not the first method called.
0989 */
0990 void chooseFirstProvider() {
0991 if (sigSpi != null) {
0992 return;
0993 }
0994 synchronized (lock) {
0995 if (sigSpi != null) {
0996 return;
0997 }
0998 if (debug != null) {
0999 int w = --warnCount;
1000 if (w >= 0) {
1001 debug
1002 .println("Signature.init() not first method "
1003 + "called, disabling delayed provider selection");
1004 if (w == 0) {
1005 debug
1006 .println("Further warnings of this type will "
1007 + "be suppressed");
1008 }
1009 new Exception("Call trace").printStackTrace();
1010 }
1011 }
1012 Exception lastException = null;
1013 while ((firstService != null)
1014 || serviceIterator.hasNext()) {
1015 Service s;
1016 if (firstService != null) {
1017 s = firstService;
1018 firstService = null;
1019 } else {
1020 s = serviceIterator.next();
1021 }
1022 if (isSpi(s) == false) {
1023 continue;
1024 }
1025 try {
1026 sigSpi = newInstance(s);
1027 provider = s.getProvider();
1028 // not needed any more
1029 firstService = null;
1030 serviceIterator = null;
1031 return;
1032 } catch (NoSuchAlgorithmException e) {
1033 lastException = e;
1034 }
1035 }
1036 ProviderException e = new ProviderException(
1037 "Could not construct SignatureSpi instance");
1038 if (lastException != null) {
1039 e.initCause(lastException);
1040 }
1041 throw e;
1042 }
1043 }
1044
1045 private void chooseProvider(int type, Key key,
1046 SecureRandom random) throws InvalidKeyException {
1047 synchronized (lock) {
1048 if (sigSpi != null) {
1049 init(sigSpi, type, key, random);
1050 return;
1051 }
1052 Exception lastException = null;
1053 while ((firstService != null)
1054 || serviceIterator.hasNext()) {
1055 Service s;
1056 if (firstService != null) {
1057 s = firstService;
1058 firstService = null;
1059 } else {
1060 s = serviceIterator.next();
1061 }
1062 // if provider says it does not support this key, ignore it
1063 if (s.supportsParameter(key) == false) {
1064 continue;
1065 }
1066 // if instance is not a SignatureSpi, ignore it
1067 if (isSpi(s) == false) {
1068 continue;
1069 }
1070 try {
1071 SignatureSpi spi = newInstance(s);
1072 init(spi, type, key, random);
1073 provider = s.getProvider();
1074 sigSpi = spi;
1075 firstService = null;
1076 serviceIterator = null;
1077 return;
1078 } catch (Exception e) {
1079 // NoSuchAlgorithmException from newInstance()
1080 // InvalidKeyException from init()
1081 // RuntimeException (ProviderException) from init()
1082 if (lastException == null) {
1083 lastException = e;
1084 }
1085 }
1086 }
1087 // no working provider found, fail
1088 if (lastException instanceof InvalidKeyException) {
1089 throw (InvalidKeyException) lastException;
1090 }
1091 if (lastException instanceof RuntimeException) {
1092 throw (RuntimeException) lastException;
1093 }
1094 String k = (key != null) ? key.getClass().getName()
1095 : "(null)";
1096 throw new InvalidKeyException(
1097 "No installed provider supports this key: " + k,
1098 lastException);
1099 }
1100 }
1101
1102 private final static int I_PUB = 1;
1103 private final static int I_PRIV = 2;
1104 private final static int I_PRIV_SR = 3;
1105
1106 private void init(SignatureSpi spi, int type, Key key,
1107 SecureRandom random) throws InvalidKeyException {
1108 switch (type) {
1109 case I_PUB:
1110 spi.engineInitVerify((PublicKey) key);
1111 break;
1112 case I_PRIV:
1113 spi.engineInitSign((PrivateKey) key);
1114 break;
1115 case I_PRIV_SR:
1116 spi.engineInitSign((PrivateKey) key, random);
1117 break;
1118 default:
1119 throw new AssertionError("Internal error: " + type);
1120 }
1121 }
1122
1123 protected void engineInitVerify(PublicKey publicKey)
1124 throws InvalidKeyException {
1125 if (sigSpi != null) {
1126 sigSpi.engineInitVerify(publicKey);
1127 } else {
1128 chooseProvider(I_PUB, publicKey, null);
1129 }
1130 }
1131
1132 protected void engineInitSign(PrivateKey privateKey)
1133 throws InvalidKeyException {
1134 if (sigSpi != null) {
1135 sigSpi.engineInitSign(privateKey);
1136 } else {
1137 chooseProvider(I_PRIV, privateKey, null);
1138 }
1139 }
1140
1141 protected void engineInitSign(PrivateKey privateKey,
1142 SecureRandom sr) throws InvalidKeyException {
1143 if (sigSpi != null) {
1144 sigSpi.engineInitSign(privateKey, sr);
1145 } else {
1146 chooseProvider(I_PRIV_SR, privateKey, sr);
1147 }
1148 }
1149
1150 protected void engineUpdate(byte b) throws SignatureException {
1151 chooseFirstProvider();
1152 sigSpi.engineUpdate(b);
1153 }
1154
1155 protected void engineUpdate(byte[] b, int off, int len)
1156 throws SignatureException {
1157 chooseFirstProvider();
1158 sigSpi.engineUpdate(b, off, len);
1159 }
1160
1161 protected void engineUpdate(ByteBuffer data) {
1162 chooseFirstProvider();
1163 sigSpi.engineUpdate(data);
1164 }
1165
1166 protected byte[] engineSign() throws SignatureException {
1167 chooseFirstProvider();
1168 return sigSpi.engineSign();
1169 }
1170
1171 protected int engineSign(byte[] outbuf, int offset, int len)
1172 throws SignatureException {
1173 chooseFirstProvider();
1174 return sigSpi.engineSign(outbuf, offset, len);
1175 }
1176
1177 protected boolean engineVerify(byte[] sigBytes)
1178 throws SignatureException {
1179 chooseFirstProvider();
1180 return sigSpi.engineVerify(sigBytes);
1181 }
1182
1183 protected boolean engineVerify(byte[] sigBytes, int offset,
1184 int length) throws SignatureException {
1185 chooseFirstProvider();
1186 return sigSpi.engineVerify(sigBytes, offset, length);
1187 }
1188
1189 protected void engineSetParameter(String param, Object value)
1190 throws InvalidParameterException {
1191 chooseFirstProvider();
1192 sigSpi.engineSetParameter(param, value);
1193 }
1194
1195 protected void engineSetParameter(AlgorithmParameterSpec params)
1196 throws InvalidAlgorithmParameterException {
1197 chooseFirstProvider();
1198 sigSpi.engineSetParameter(params);
1199 }
1200
1201 protected Object engineGetParameter(String param)
1202 throws InvalidParameterException {
1203 chooseFirstProvider();
1204 return sigSpi.engineGetParameter(param);
1205 }
1206
1207 protected AlgorithmParameters engineGetParameters() {
1208 chooseFirstProvider();
1209 return sigSpi.engineGetParameters();
1210 }
1211 }
1212
1213 // adapter for RSA/ECB/PKCS1Padding ciphers
1214 private static class CipherAdapter extends SignatureSpi {
1215
1216 private final Cipher cipher;
1217
1218 private ByteArrayOutputStream data;
1219
1220 CipherAdapter(Cipher cipher) {
1221 this .cipher = cipher;
1222 }
1223
1224 protected void engineInitVerify(PublicKey publicKey)
1225 throws InvalidKeyException {
1226 cipher.init(Cipher.DECRYPT_MODE, publicKey);
1227 if (data == null) {
1228 data = new ByteArrayOutputStream(128);
1229 } else {
1230 data.reset();
1231 }
1232 }
1233
1234 protected void engineInitSign(PrivateKey privateKey)
1235 throws InvalidKeyException {
1236 cipher.init(Cipher.ENCRYPT_MODE, privateKey);
1237 data = null;
1238 }
1239
1240 protected void engineInitSign(PrivateKey privateKey,
1241 SecureRandom random) throws InvalidKeyException {
1242 cipher.init(Cipher.ENCRYPT_MODE, privateKey, random);
1243 data = null;
1244 }
1245
1246 protected void engineUpdate(byte b) throws SignatureException {
1247 engineUpdate(new byte[] { b }, 0, 1);
1248 }
1249
1250 protected void engineUpdate(byte[] b, int off, int len)
1251 throws SignatureException {
1252 if (data != null) {
1253 data.write(b, off, len);
1254 return;
1255 }
1256 byte[] out = cipher.update(b, off, len);
1257 if ((out != null) && (out.length != 0)) {
1258 throw new SignatureException(
1259 "Cipher unexpectedly returned data");
1260 }
1261 }
1262
1263 protected byte[] engineSign() throws SignatureException {
1264 try {
1265 return cipher.doFinal();
1266 } catch (IllegalBlockSizeException e) {
1267 throw new SignatureException("doFinal() failed", e);
1268 } catch (BadPaddingException e) {
1269 throw new SignatureException("doFinal() failed", e);
1270 }
1271 }
1272
1273 protected boolean engineVerify(byte[] sigBytes)
1274 throws SignatureException {
1275 try {
1276 byte[] out = cipher.doFinal(sigBytes);
1277 byte[] dataBytes = data.toByteArray();
1278 data.reset();
1279 return Arrays.equals(out, dataBytes);
1280 } catch (BadPaddingException e) {
1281 // e.g. wrong public key used
1282 // return false rather than throwing exception
1283 return false;
1284 } catch (IllegalBlockSizeException e) {
1285 throw new SignatureException("doFinal() failed", e);
1286 }
1287 }
1288
1289 protected void engineSetParameter(String param, Object value)
1290 throws InvalidParameterException {
1291 throw new InvalidParameterException(
1292 "Parameters not supported");
1293 }
1294
1295 protected Object engineGetParameter(String param)
1296 throws InvalidParameterException {
1297 throw new InvalidParameterException(
1298 "Parameters not supported");
1299 }
1300
1301 }
1302
1303 }
|