Source for java.security.Signature

   1: /* Signature.java --- Signature Class
   2:    Copyright (C) 1999, 2002, 2003, 2004  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package java.security;
  40: 
  41: import gnu.java.security.Engine;
  42: 
  43: import java.security.cert.Certificate;
  44: import java.security.cert.X509Certificate;
  45: import java.security.spec.AlgorithmParameterSpec;
  46: 
  47: /**
  48:  * <code>Signature</code> is used to provide an interface to digital signature
  49:  * algorithms. Digital signatures provide authentication and data integrity of
  50:  * digital data.
  51:  * 
  52:  * <p>The GNU provider provides the NIST standard DSA which uses DSA and SHA-1.
  53:  * It can be specified by SHA/DSA, SHA-1/DSA or its OID. If the RSA signature
  54:  * algorithm is provided then it could be MD2/RSA. MD5/RSA, or SHA-1/RSA. The
  55:  * algorithm must be specified because there is no default.</p>
  56:  * 
  57:  * <p>Signature provides implementation-independent algorithms which are
  58:  * requested by the user through the <code>getInstance()<?code> methods. It can
  59:  * be requested by specifying just the algorithm name or by specifying both the
  60:  * algorithm name and provider name.</p>
  61:  * 
  62:  * <p>The three phases of using <code>Signature</code> are:</p>
  63:  * 
  64:  * <ol>
  65:  *   <li>Initializing:
  66:  *     <ul>
  67:  *       <li>It must be initialized with a private key for signing.</li>
  68:  *       <li>It must be initialized with a public key for verifying.</li>
  69:  *   </li>
  70:  *   
  71:  *   <li>Updating:
  72:  *   <p>Update the bytes for signing or verifying with calls to update.</p>
  73:  *   </li>
  74:  *   
  75:  *   <li>Signing or Verify the signature on the currently stored bytes by
  76:  *   calling sign or verify.</li>
  77:  * </ol>
  78:  *
  79:  * @author Mark Benvenuto  (ivymccough@worldnet.att.net)
  80:  */
  81: public abstract class Signature extends SignatureSpi
  82: {
  83:   /** Service name for signatures. */
  84:   private static final String SIGNATURE = "Signature";
  85: 
  86:   /**
  87:    * Possible state value which signifies that this instance has not yet been
  88:    * initialized.
  89:    */
  90:   protected static final int UNINITIALIZED = 0;
  91: 
  92:   /**
  93:    * Possible state value which signifies that this instance has been
  94:    * initialized for signing purposes.
  95:    */
  96:   protected static final int SIGN = 2;
  97: 
  98:   /**
  99:    * Possible state value which signifies that this instance has been
 100:    * initialized for verification purposes.
 101:    */
 102:   protected static final int VERIFY = 3;
 103: 
 104:   /** Current sate of this instance. */
 105:   protected int state = UNINITIALIZED;
 106: 
 107:   private String algorithm;
 108:   Provider provider;
 109: 
 110:   // Constructor.
 111:   // ------------------------------------------------------------------------
 112: 
 113:   /**
 114:    * Constructs a new <code>Signature</code> instance for a designated digital
 115:    * signature algorithm.
 116:    * 
 117:    * @param algorithm
 118:    *          the algorithm to use.
 119:    */
 120:   protected Signature(String algorithm)
 121:   {
 122:     this.algorithm = algorithm;
 123:     state = UNINITIALIZED;
 124:   }
 125: 
 126:   /**
 127:    * Returns an instance of <code>Signature</code> representing the specified
 128:    * signature.
 129:    * 
 130:    * @param algorithm
 131:    *          the algorithm to use.
 132:    * @return a new instance repesenting the desired algorithm.
 133:    * @throws NoSuchAlgorithmException
 134:    *           if the algorithm is not implemented by any provider.
 135:    */
 136:   public static Signature getInstance(String algorithm)
 137:     throws NoSuchAlgorithmException
 138:   {
 139:     Provider[] p = Security.getProviders();
 140:     for (int i = 0; i < p.length; i++)
 141:       {
 142:         try
 143:           {
 144:             return getInstance(algorithm, p[i]);
 145:           }
 146:     catch (NoSuchAlgorithmException e)
 147:       {
 148:         // Ignored.
 149:       }
 150:       }
 151: 
 152:     throw new NoSuchAlgorithmException(algorithm);
 153:   }
 154: 
 155:   /**
 156:    * Returns an instance of <code>Signature</code> representing the specified
 157:    * signature from the named provider.
 158:    * 
 159:    * @param algorithm
 160:    *          the algorithm to use.
 161:    * @param provider
 162:    *          the name of the provider to use.
 163:    * @return a new instance repesenting the desired algorithm.
 164:    * @throws IllegalArgumentException if <code>provider</code> is
 165:    *           <code>null</code> or is an empty string.
 166:    * @throws NoSuchProviderException
 167:    *           if the named provider was not found.
 168:    * @throws NoSuchAlgorithmException
 169:    *           if the algorithm is not implemented by the named provider.
 170:    */
 171:   public static Signature getInstance(String algorithm, String provider)
 172:     throws NoSuchAlgorithmException, NoSuchProviderException
 173:   {
 174:     if (provider == null || provider.length() == 0)
 175:       throw new IllegalArgumentException("Illegal provider");
 176: 
 177:     Provider p = Security.getProvider(provider);
 178:     if (p == null)
 179:       throw new NoSuchProviderException(provider);
 180: 
 181:     return getInstance(algorithm, p);
 182:   }
 183: 
 184:   /**
 185:    * Returns an instance of <code>Signature</code> representing the specified
 186:    * signature from the specified {@link Provider}.
 187:    * 
 188:    * @param algorithm
 189:    *          the algorithm to use.
 190:    * @param provider
 191:    *          the {@link Provider} to use.
 192:    * @return a new instance repesenting the desired algorithm.
 193:    * @throws NoSuchAlgorithmException
 194:    *           if the algorithm is not implemented by the {@link Provider}.
 195:    */
 196:   public static Signature getInstance(String algorithm, Provider provider)
 197:     throws NoSuchAlgorithmException
 198:   {
 199:     if (provider == null)
 200:       throw new IllegalArgumentException("Illegal provider");
 201: 
 202:     Signature result = null;
 203:     Object o = null;
 204:     try
 205:       {
 206:         o = Engine.getInstance(SIGNATURE, algorithm, provider);
 207:       }
 208:     catch (java.lang.reflect.InvocationTargetException ite)
 209:       {
 210:         throw new NoSuchAlgorithmException(algorithm);
 211:       }
 212: 
 213:     if (o instanceof SignatureSpi)
 214:       {
 215:         result = new DummySignature((SignatureSpi) o, algorithm);
 216:       }
 217:     else if (o instanceof Signature)
 218:       {
 219:         result = (Signature) o;
 220:         result.algorithm = algorithm;
 221:       }
 222:     else
 223:       {
 224:         throw new NoSuchAlgorithmException(algorithm);
 225:       }
 226:     result.provider = provider;
 227:     return result;
 228:   }
 229: 
 230:   /**
 231:    * Returns the {@link Provider} of this instance.
 232:    * 
 233:    * @return the {@link Provider} of this instance.
 234:    */
 235:   public final Provider getProvider()
 236:   {
 237:     return provider;
 238:   }
 239: 
 240:   /**
 241:    * Initializes this instance with the public key for verification purposes.
 242:    * 
 243:    * @param publicKey
 244:    *          the public key to verify with.
 245:    * @throws InvalidKeyException
 246:    *           if the key is invalid.
 247:    */
 248:   public final void initVerify(PublicKey publicKey) throws InvalidKeyException
 249:   {
 250:     state = VERIFY;
 251:     engineInitVerify(publicKey);
 252:   }
 253: 
 254:   /**
 255:    * Verify a signature with a designated {@link Certificate}. This is a FIPS
 256:    * 140-1 compatible method since it verifies a signature with a certificate.
 257:    * 
 258:    * <p>If the {@link Certificate} is an X.509 one, has a <i>KeyUsage</i>
 259:    * parameter and that parameter indicates this key is not to be used for
 260:    * signing then an exception is thrown.</p>
 261:    * 
 262:    * @param certificate
 263:    *          a {@link Certificate} containing a public key to verify with.
 264:    * @throws InvalidKeyException if the key is invalid.
 265:    */
 266:   public final void initVerify(Certificate certificate)
 267:     throws InvalidKeyException
 268:   {
 269:     state = VERIFY;
 270:     if (certificate.getType().equals("X509"))
 271:       {
 272:         X509Certificate cert = (X509Certificate) certificate;
 273:         boolean[]array = cert.getKeyUsage();
 274:         if (array != null && array[0] == false)
 275:           throw new InvalidKeyException(
 276:               "KeyUsage of this Certificate indicates it cannot be used for digital signing");
 277:       }
 278:     this.initVerify(certificate.getPublicKey());
 279:   }
 280: 
 281:   /**
 282:    * Initializes this class with the private key for signing purposes.
 283:    * 
 284:    * @param privateKey
 285:    *          the private key to sign with.
 286:    * @throws InvalidKeyException
 287:    *           if the key is invalid.
 288:    */
 289:   public final void initSign(PrivateKey privateKey) throws InvalidKeyException
 290:   {
 291:     state = SIGN;
 292:     engineInitSign(privateKey);
 293:   }
 294: 
 295:   /**
 296:    * Initializes this class with the private key and source of randomness for
 297:    * signing purposes.
 298:    * 
 299:    * @param privateKey
 300:    *          the private key to sign with.
 301:    * @param random
 302:    *          the {@link SecureRandom} to use.
 303:    * @throws InvalidKeyException
 304:    *           if the key is invalid.
 305:    */
 306:   public final void initSign(PrivateKey privateKey, SecureRandom random)
 307:     throws InvalidKeyException
 308:   {
 309:     state = SIGN;
 310:     engineInitSign(privateKey, random);
 311:   }
 312: 
 313:   /**
 314:    * Returns the signature bytes of all the data fed to this instance. The
 315:    * format of the output depends on the underlying signature algorithm.
 316:    * 
 317:    * @return the signature bytes.
 318:    * @throws SignatureException
 319:    *           if the engine is not properly initialized.
 320:    */
 321:   public final byte[] sign() throws SignatureException
 322:   {
 323:     if (state == SIGN)
 324:       return engineSign();
 325:     else
 326:       throw new SignatureException();
 327:   }
 328: 
 329:   /**
 330:    * Generates signature bytes of all the data fed to this instance and stores
 331:    * it in the designated array. The format of the result depends on the
 332:    * underlying signature algorithm.
 333:    * 
 334:    * <p>After calling this method, the instance is reset to its initial state
 335:    * and can then be used to generate additional signatures.</p>
 336:    * 
 337:    * <p><b>IMPLEMENTATION NOTE:</b> Neither this method nor the GNU provider
 338:    * will return partial digests. If <code>len</code> is less than the
 339:    * signature length, this method will throw a {@link SignatureException}. If
 340:    * it is greater than or equal then it is ignored.</p>
 341:    * 
 342:    * @param outbuf
 343:    *          array of bytes of where to store the resulting signature bytes.
 344:    * @param offset
 345:    *          the offset to start at in the array.
 346:    * @param len
 347:    *          the number of the bytes to use in the array.
 348:    * @return the real number of bytes used.
 349:    * @throws SignatureException
 350:    *           if the engine is not properly initialized.
 351:    * @since 1.2
 352:    */
 353:   public final int sign(byte[] outbuf, int offset, int len)
 354:     throws SignatureException
 355:   {
 356:     if (state == SIGN)
 357:       return engineSign(outbuf, offset, len);
 358:     else
 359:       throw new SignatureException();
 360:   }
 361: 
 362:   /**
 363:    * Verifies a designated signature.
 364:    * 
 365:    * @param signature
 366:    *          the signature bytes to verify.
 367:    * @return <code>true</code> if verified, <code>false</code> otherwise.
 368:    * @throws SignatureException
 369:    *           if the engine is not properly initialized or the signature does
 370:    *           not check.
 371:    */
 372:   public final boolean verify(byte[]signature) throws SignatureException
 373:   {
 374:     if (state == VERIFY)
 375:       return engineVerify(signature);
 376:     else
 377:       throw new SignatureException();
 378:   }
 379: 
 380:   /**
 381:    * Verifies a designated signature.
 382:    * 
 383:    * @param signature
 384:    *          the signature bytes to verify.
 385:    * @param offset
 386:    *          the offset to start at in the array.
 387:    * @param length
 388:    *          the number of the bytes to use from the array.
 389:    * @return <code>true</code> if verified, <code>false</code> otherwise.
 390:    * @throws IllegalArgumentException
 391:    *           if the <code>signature</code> byte array is <code>null</code>,
 392:    *           or the <code>offset</code> or <code>length</code> is less
 393:    *           than <code>0</code>, or the sum of the <code>offset</code>
 394:    *           and <code>length</code> is greater than the length of the
 395:    *           <code>signature</code> byte array.
 396:    * @throws SignatureException
 397:    *           if the engine is not properly initialized or the signature does
 398:    *           not check.
 399:    */
 400:   public final boolean verify(byte[] signature, int offset, int length)
 401:     throws SignatureException
 402:   {
 403:     if (state != VERIFY)
 404:       throw new SignatureException("illegal state");
 405: 
 406:     if (signature == null)
 407:       throw new IllegalArgumentException("signature is null");
 408:     if (offset < 0)
 409:       throw new IllegalArgumentException("offset is less than 0");
 410:     if (length < 0)
 411:       throw new IllegalArgumentException("length is less than 0");
 412:     if (offset + length < signature.length)
 413:       throw new IllegalArgumentException("range is out of bounds");
 414: 
 415:     return engineVerify(signature, offset, length);
 416:   }
 417: 
 418:   /**
 419:    * Updates the data to be signed or verified with the specified byte.
 420:    * 
 421:    * @param b
 422:    *          the byte to update with.
 423:    * @throws SignatureException
 424:    *           if the engine is not properly initialized.
 425:    */
 426:   public final void update(byte b) throws SignatureException
 427:   {
 428:     if (state != UNINITIALIZED)
 429:       engineUpdate(b);
 430:     else
 431:       throw new SignatureException();
 432:   }
 433: 
 434:   /**
 435:    * Updates the data to be signed or verified with the specified bytes.
 436:    * 
 437:    * @param data
 438:    *          the array of bytes to use.
 439:    * @throws SignatureException
 440:    *           if the engine is not properly initialized.
 441:    */
 442:   public final void update(byte[]data) throws SignatureException
 443:   {
 444:     if (state != UNINITIALIZED)
 445:       engineUpdate(data, 0, data.length);
 446:     else
 447:       throw new SignatureException();
 448:   }
 449: 
 450:   /**
 451:    * Updates the data to be signed or verified with the specified bytes.
 452:    * 
 453:    * @param data
 454:    *          an array of bytes to use.
 455:    * @param off
 456:    *          the offset to start at in the array.
 457:    * @param len
 458:    *          the number of bytes to use from the array.
 459:    * @throws SignatureException
 460:    *           if the engine is not properly initialized.
 461:    */
 462:   public final void update(byte[]data, int off, int len)
 463:     throws SignatureException
 464:   {
 465:     if (state != UNINITIALIZED)
 466:       engineUpdate(data, off, len);
 467:     else
 468:       throw new SignatureException();
 469:   }
 470: 
 471:   /**
 472:    * Returns the name of the algorithm currently used. The names of algorithms
 473:    * are usually SHA/DSA or SHA/RSA.
 474:    * 
 475:    * @return name of algorithm.
 476:    */
 477:   public final String getAlgorithm()
 478:   {
 479:     return algorithm;
 480:   }
 481: 
 482:   /**
 483:    * Returns a rstring representation of this instance.
 484:    * 
 485:    * @return a rstring representation of this instance.
 486:    */
 487:   public String toString()
 488:   {
 489:     return (algorithm + " Signature");
 490:   }
 491: 
 492:   /**
 493:    * Sets the specified algorithm parameter to the specified value.
 494:    * 
 495:    * @param param
 496:    *          the parameter name.
 497:    * @param value
 498:    *          the parameter value.
 499:    * @throws InvalidParameterException
 500:    *           if the parameter is invalid, the parameter is already set and
 501:    *           can not be changed, a security exception occured, etc.
 502:    * @deprecated use the other setParameter
 503:    */
 504:   public final void setParameter(String param, Object value)
 505:     throws InvalidParameterException
 506:   {
 507:     engineSetParameter(param, value);
 508:   }
 509: 
 510:   /**
 511:    * Sets the signature engine with the specified {@link AlgorithmParameterSpec}.
 512:    * 
 513:    * <p>By default, and unless overriden by the concrete SPI, this method always
 514:    * throws an {@link UnsupportedOperationException}.</p>
 515:    * 
 516:    * @param params
 517:    *          the parameters to use for intializing this instance.
 518:    * @throws InvalidParameterException
 519:    *           if the parameter is invalid, the parameter is already set and
 520:    *           cannot be changed, a security exception occured, etc.
 521:    */
 522:   public final void setParameter(AlgorithmParameterSpec params)
 523:     throws InvalidAlgorithmParameterException
 524:   {
 525:     engineSetParameter(params);
 526:   }
 527: 
 528:   /**
 529:    * Return the parameters of the algorithm used in this instance as an
 530:    * {@link AlgorithmParameters}.
 531:    * 
 532:    * @return the parameters used with this instance, or <code>null</code> if
 533:    *         this instance does not use any parameters.
 534:    */
 535:   public final AlgorithmParameters getParameters()
 536:   {
 537:     return engineGetParameters();
 538:   }
 539: 
 540:   /**
 541:    * Returns the value for the specified algorithm parameter.
 542:    * 
 543:    * @param param
 544:    *          the parameter name.
 545:    * @return the parameter value.
 546:    * @throws InvalidParameterException
 547:    *           if the parameter is invalid.
 548:    * @deprecated use the other getParameter
 549:    */
 550:   public final Object getParameter(String param)
 551:     throws InvalidParameterException
 552:   {
 553:     return engineGetParameter(param);
 554:   }
 555: 
 556:   /**
 557:    * Returns a clone of this instance.
 558:    * 
 559:    * @return a clone of this instace.
 560:    * @throws CloneNotSupportedException
 561:    *           if the implementation does not support cloning.
 562:    */
 563:   public Object clone() throws CloneNotSupportedException
 564:   {
 565:     return super.clone();
 566:   }
 567: }