GNU Classpath (0.20) | |
Frames | No Frames |
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: * <p>This <code>Signature</code> class is used to provide applications the 49: * functionality of a digital signature algorithm. Digital signatures are used 50: * for authentication and integrity assurance of digital data.</p> 51: * 52: * <p>The signature algorithm can be, among others, the NIST standard <i>DSS</i>, 53: * using <i>DSA</i> and <i>SHA-1</i>. The <i>DSA</i> algorithm using the 54: * <i>SHA-1</i> message digest algorithm can be specified as <code>SHA1withDSA 55: * </code>. In the case of <i>RSA</i>, there are multiple choices for the 56: * message digest algorithm, so the signing algorithm could be specified as, for 57: * example, <code>MD2withRSA</code>, <code>MD5withRSA</code>, or 58: * <code>SHA1withRSA</code>. The algorithm name must be specified, as there is 59: * no default.</p> 60: * 61: * <p>Like other algorithm-based classes in Java Security, <code>Signature</code> 62: * provides implementation-independent algorithms, whereby a caller (application 63: * code) requests a particular signature algorithm and is handed back a properly 64: * initialized <code>Signature</code> object. It is also possible, if desired, 65: * to request a particular algorithm from a particular provider. See the 66: * <code>getInstance()</code> methods.</p> 67: * 68: * <p>Thus, there are two ways to request a <code>Signature</code> algorithm 69: * object: by specifying either just an algorithm name, or both an algorithm 70: * name and a package provider.</p> 71: * 72: * <p>If just an algorithm name is specified, the system will determine if there 73: * is an implementation of the algorithm requested available in the environment, 74: * and if there is more than one, if there is a preferred one.</p> 75: * 76: * <p>If both an algorithm name and a package provider are specified, the system 77: * will determine if there is an implementation of the algorithm in the package 78: * requested, and throw an exception if there is not.</p> 79: * 80: * <p>A <code>Signature</code> object can be used to generate and verify digital 81: * signatures.</p> 82: * 83: * <p>There are three phases to the use of a <code>Signature</code> object for 84: * either signing data or verifying a signature:</p> 85: * 86: * <ol> 87: * <li>Initialization, with either 88: * <ul> 89: * <li>a public key, which initializes the signature for verification 90: * (see <code>initVerify()</code>), or</li> 91: * <li>a private key (and optionally a Secure Random Number Generator), 92: * which initializes the signature for signing (see 93: * {@link #initSign(PrivateKey)} and {@link #initSign(PrivateKey, SecureRandom)} 94: * ).</li> 95: * </ul></li> 96: * <li>Updating<br/> 97: * Depending on the type of initialization, this will update the bytes to 98: * be signed or verified. See the update methods.<br/></li> 99: * <li>Signing or Verifying a signature on all updated bytes. See the 100: * <code>sign()</code> methods and the <code>verify()</code> method.</li> 101: * </ol> 102: * 103: * <p>Note that this class is abstract and extends from {@link SignatureSpi} for 104: * historical reasons. Application developers should only take notice of the 105: * methods defined in this <code>Signature</code> class; all the methods in the 106: * superclass are intended for cryptographic service providers who wish to 107: * supply their own implementations of digital signature algorithms. 108: * 109: * @author Mark Benvenuto (ivymccough@worldnet.att.net) 110: */ 111: public abstract class Signature extends SignatureSpi 112: { 113: /** Service name for signatures. */ 114: private static final String SIGNATURE = "Signature"; 115: 116: /** 117: * Possible <code>state</code> value, signifying that this signature object 118: * has not yet been initialized. 119: */ 120: protected static final int UNINITIALIZED = 0; 121: 122: // Constructor. 123: // ------------------------------------------------------------------------ 124: 125: /** 126: * Possible <code>state</code> value, signifying that this signature object 127: * has been initialized for signing. 128: */ 129: protected static final int SIGN = 2; 130: 131: /** 132: * Possible <code>state</code> value, signifying that this signature object 133: * has been initialized for verification. 134: */ 135: protected static final int VERIFY = 3; 136: 137: /** Current state of this signature object. */ 138: protected int state = UNINITIALIZED; 139: 140: private String algorithm; 141: Provider provider; 142: 143: /** 144: * Creates a <code>Signature</code> object for the specified algorithm. 145: * 146: * @param algorithm the standard string name of the algorithm. See Appendix A 147: * in the Java Cryptography Architecture API Specification & Reference for 148: * information about standard algorithm names. 149: */ 150: protected Signature(String algorithm) 151: { 152: this.algorithm = algorithm; 153: state = UNINITIALIZED; 154: } 155: 156: /** 157: * Generates a <code>Signature</code> object that implements the specified 158: * digest algorithm. If the default provider package provides an 159: * implementation of the requested digest algorithm, an instance of 160: * <code>Signature</code> containing that implementation is returned. If the 161: * algorithm is not available in the default package, other packages are 162: * searched. 163: * 164: * @param algorithm the standard name of the algorithm requested. See Appendix 165: * A in the Java Cryptography Architecture API Specification & Reference 166: * for information about standard algorithm names. 167: * @return the new Signature object. 168: * @throws NoSuchAlgorithmException if the algorithm is not available in the 169: * environment. 170: */ 171: public static Signature getInstance(String algorithm) 172: throws NoSuchAlgorithmException 173: { 174: Provider[] p = Security.getProviders(); 175: for (int i = 0; i < p.length; i++) 176: { 177: try 178: { 179: return getInstance(algorithm, p[i]); 180: } 181: catch (NoSuchAlgorithmException e) 182: { 183: // Ignored. 184: } 185: } 186: 187: throw new NoSuchAlgorithmException(algorithm); 188: } 189: 190: /** 191: * Generates a <code>Signature</code> object implementing the specified 192: * algorithm, as supplied from the specified provider, if such an algorithm 193: * is available from the provider. 194: * 195: * @param algorithm the name of the algorithm requested. See Appendix A in 196: * the Java Cryptography Architecture API Specification & Reference for 197: * information about standard algorithm names. 198: * @param provider the name of the provider. 199: * @return the new <code>Signature</code> object. 200: * @throws NoSuchAlgorithmException if the algorithm is not available in the 201: * package supplied by the requested provider. 202: * @throws NoSuchProviderException if the provider is not available in the 203: * environment. 204: * @throws IllegalArgumentException if the provider name is <code>null</code> 205: * or empty. 206: * @see Provider 207: */ 208: public static Signature getInstance(String algorithm, String provider) 209: throws NoSuchAlgorithmException, NoSuchProviderException 210: { 211: if (provider == null || provider.length() == 0) 212: throw new IllegalArgumentException("Illegal provider"); 213: 214: Provider p = Security.getProvider(provider); 215: if (p == null) 216: throw new NoSuchProviderException(provider); 217: 218: return getInstance(algorithm, p); 219: } 220: 221: /** 222: * Generates a <code>Signature</code> object implementing the specified 223: * algorithm, as supplied from the specified provider, if such an algorithm 224: * is available from the provider. Note: the provider doesn't have to be 225: * registered. 226: * 227: * @param algorithm the name of the algorithm requested. See Appendix A in 228: * the Java Cryptography Architecture API Specification & Reference for 229: * information about standard algorithm names. 230: * @param provider the provider. 231: * @return the new <code>Signature</code> object. 232: * @throws NoSuchAlgorithmException if the <code>algorithm</code> is not 233: * available in the package supplied by the requested <code>provider</code>. 234: * @throws IllegalArgumentException if the <code>provider</code> is 235: * <code>null</code>. 236: * @since 1.4 237: * @see Provider 238: */ 239: public static Signature getInstance(String algorithm, Provider provider) 240: throws NoSuchAlgorithmException 241: { 242: if (provider == null) 243: throw new IllegalArgumentException("Illegal provider"); 244: 245: Signature result = null; 246: Object o = null; 247: try 248: { 249: o = Engine.getInstance(SIGNATURE, algorithm, provider); 250: } 251: catch (java.lang.reflect.InvocationTargetException ite) 252: { 253: throw new NoSuchAlgorithmException(algorithm); 254: } 255: 256: if (o instanceof SignatureSpi) 257: { 258: result = new DummySignature((SignatureSpi) o, algorithm); 259: } 260: else if (o instanceof Signature) 261: { 262: result = (Signature) o; 263: result.algorithm = algorithm; 264: } 265: else 266: { 267: throw new NoSuchAlgorithmException(algorithm); 268: } 269: result.provider = provider; 270: return result; 271: } 272: 273: /** 274: * Returns the provider of this signature object. 275: * 276: * @return the provider of this signature object. 277: */ 278: public final Provider getProvider() 279: { 280: return provider; 281: } 282: 283: /** 284: * Initializes this object for verification. If this method is called again 285: * with a different argument, it negates the effect of this call. 286: * 287: * @param publicKey the public key of the identity whose signature is going 288: * to be verified. 289: * @throws InvalidKeyException if the key is invalid. 290: */ 291: public final void initVerify(PublicKey publicKey) throws InvalidKeyException 292: { 293: state = VERIFY; 294: engineInitVerify(publicKey); 295: } 296: 297: /** 298: * <p>Initializes this object for verification, using the public key from the 299: * given certificate.</p> 300: * 301: * <p>If the certificate is of type <i>X.509</i> and has a <i>key usage</i> 302: * extension field marked as <i>critical</i>, and the value of the <i>key 303: * usage</i> extension field implies that the public key in the certificate 304: * and its corresponding private key are not supposed to be used for digital 305: * signatures, an {@link InvalidKeyException} is thrown.</p> 306: * 307: * @param certificate the certificate of the identity whose signature is 308: * going to be verified. 309: * @throws InvalidKeyException if the public key in the certificate is not 310: * encoded properly or does not include required parameter information or 311: * cannot be used for digital signature purposes. 312: */ 313: public final void initVerify(Certificate certificate) 314: throws InvalidKeyException 315: { 316: state = VERIFY; 317: if (certificate.getType().equals("X509")) 318: { 319: X509Certificate cert = (X509Certificate) certificate; 320: boolean[]array = cert.getKeyUsage(); 321: if (array != null && array[0] == false) 322: throw new InvalidKeyException( 323: "KeyUsage of this Certificate indicates it cannot be used for digital signing"); 324: } 325: this.initVerify(certificate.getPublicKey()); 326: } 327: 328: /** 329: * Initialize this object for signing. If this method is called again with a 330: * different argument, it negates the effect of this call. 331: * 332: * @param privateKey the private key of the identity whose signature is going 333: * to be generated. 334: * @throws InvalidKeyException if the key is invalid. 335: */ 336: public final void initSign(PrivateKey privateKey) throws InvalidKeyException 337: { 338: state = SIGN; 339: engineInitSign(privateKey); 340: } 341: 342: /** 343: * Initialize this object for signing. If this method is called again with a 344: * different argument, it negates the effect of this call. 345: * 346: * @param privateKey the private key of the identity whose signature is going 347: * to be generated. 348: * @param random the source of randomness for this signature. 349: * @throws InvalidKeyException if the key is invalid. 350: */ 351: public final void initSign(PrivateKey privateKey, SecureRandom random) 352: throws InvalidKeyException 353: { 354: state = SIGN; 355: engineInitSign(privateKey, random); 356: } 357: 358: /** 359: * <p>Returns the signature bytes of all the data updated. The format of the 360: * signature depends on the underlying signature scheme.</p> 361: * 362: * <p>A call to this method resets this signature object to the state it was 363: * in when previously initialized for signing via a call to 364: * <code>initSign(PrivateKey)</code>. That is, the object is reset and 365: * available to generate another signature from the same signer, if desired, 366: * via new calls to <code>update()</code> and <code>sign()</code>.</p> 367: * 368: * @return the signature bytes of the signing operation's result. 369: * @throws SignatureException if this signature object is not initialized 370: * properly. 371: */ 372: public final byte[] sign() throws SignatureException 373: { 374: if (state == SIGN) 375: return engineSign(); 376: else 377: throw new SignatureException(); 378: } 379: 380: /** 381: * <p>Finishes the signature operation and stores the resulting signature 382: * bytes in the provided buffer <code>outbuf</code>, starting at <code>offset 383: * </code>. The format of the signature depends on the underlying signature 384: * scheme.</p> 385: * 386: * <p>This signature object is reset to its initial state (the state it was 387: * in after a call to one of the <code>initSign()</code> methods) and can be 388: * reused to generate further signatures with the same private key.</p> 389: * 390: * @param outbuf buffer for the signature result. 391: * @param offset offset into outbuf where the signature is stored. 392: * @param len number of bytes within outbuf allotted for the signature. 393: * @return the number of bytes placed into outbuf. 394: * @throws SignatureException if an error occurs or len is less than the 395: * actual signature length. 396: * @since 1.2 397: */ 398: public final int sign(byte[] outbuf, int offset, int len) 399: throws SignatureException 400: { 401: if (state == SIGN) 402: return engineSign(outbuf, offset, len); 403: else 404: throw new SignatureException(); 405: } 406: 407: /** 408: * <p>Verifies the passed-in signature.</p> 409: * 410: * <p>A call to this method resets this signature object to the state it was 411: * in when previously initialized for verification via a call to 412: * <code>initVerify(PublicKey)</code>. That is, the object is reset and 413: * available to verify another signature from the identity whose public key 414: * was specified in the call to <code>initVerify()</code>.</p> 415: * 416: * @param signature the signature bytes to be verified. 417: * @return <code>true</code> if the signature was verified, <code>false</code> 418: * if not. 419: * @throws SignatureException if this signature object is not initialized 420: * properly, or the passed-in signature is improperly encoded or of the wrong 421: * type, etc. 422: */ 423: public final boolean verify(byte[]signature) throws SignatureException 424: { 425: if (state == VERIFY) 426: return engineVerify(signature); 427: else 428: throw new SignatureException(); 429: } 430: 431: /** 432: * <p>Verifies the passed-in <code>signature</code> in the specified array of 433: * bytes, starting at the specified <code>offset</code>.</p> 434: * 435: * <p>A call to this method resets this signature object to the state it was 436: * in when previously initialized for verification via a call to 437: * <code>initVerify(PublicKey)</code>. That is, the object is reset and 438: * available to verify another signature from the identity whose public key 439: * was specified in the call to <code>initVerify()</code>.</p> 440: * 441: * @param signature the signature bytes to be verified. 442: * @param offset the offset to start from in the array of bytes. 443: * @param length the number of bytes to use, starting at offset. 444: * @return <code>true</code> if the signature was verified, <code>false</code> 445: * if not. 446: * @throws SignatureException if this signature object is not initialized 447: * properly, or the passed-in <code>signature</code> is improperly encoded or 448: * of the wrong type, etc. 449: * @throws IllegalArgumentException if the <code>signature</code> byte array 450: * is <code>null</code>, or the <code>offset</code> or <code>length</code> is 451: * less than <code>0</code>, or the sum of the <code>offset</code> and 452: * <code>length</code> is greater than the length of the <code>signature</code> 453: * byte array. 454: */ 455: public final boolean verify(byte[] signature, int offset, int length) 456: throws SignatureException 457: { 458: if (state != VERIFY) 459: throw new SignatureException("illegal state"); 460: 461: if (signature == null) 462: throw new IllegalArgumentException("signature is null"); 463: if (offset < 0) 464: throw new IllegalArgumentException("offset is less than 0"); 465: if (length < 0) 466: throw new IllegalArgumentException("length is less than 0"); 467: if (offset + length < signature.length) 468: throw new IllegalArgumentException("range is out of bounds"); 469: 470: return engineVerify(signature, offset, length); 471: } 472: 473: /** 474: * Updates the data to be signed or verified by a byte. 475: * 476: * @param b the byte to use for the update. 477: * @throws SignatureException if this signature object is not initialized 478: * properly. 479: */ 480: public final void update(byte b) throws SignatureException 481: { 482: if (state != UNINITIALIZED) 483: engineUpdate(b); 484: else 485: throw new SignatureException(); 486: } 487: 488: /** 489: * Updates the data to be signed or verified, using the specified array of 490: * bytes. 491: * 492: * @param data the byte array to use for the update. 493: * @throws SignatureException if this signature object is not initialized 494: * properly. 495: */ 496: public final void update(byte[]data) throws SignatureException 497: { 498: if (state != UNINITIALIZED) 499: engineUpdate(data, 0, data.length); 500: else 501: throw new SignatureException(); 502: } 503: 504: /** 505: * Updates the data to be signed or verified, using the specified array of 506: * bytes, starting at the specified offset. 507: * 508: * @param data the array of bytes. 509: * @param off the offset to start from in the array of bytes. 510: * @param len the number of bytes to use, starting at offset. 511: * @throws SignatureException if this signature object is not initialized 512: * properly. 513: */ 514: public final void update(byte[]data, int off, int len) 515: throws SignatureException 516: { 517: if (state != UNINITIALIZED) 518: engineUpdate(data, off, len); 519: else 520: throw new SignatureException(); 521: } 522: 523: /** 524: * Returns the name of the algorithm for this signature object. 525: * 526: * @return the name of the algorithm for this signature object. 527: */ 528: public final String getAlgorithm() 529: { 530: return algorithm; 531: } 532: 533: /** 534: * Returns a string representation of this signature object, providing 535: * information that includes the state of the object and the name of the 536: * algorithm used. 537: * 538: * @return a string representation of this signature object. 539: */ 540: public String toString() 541: { 542: return (algorithm + " Signature"); 543: } 544: 545: /** 546: * Sets the specified algorithm parameter to the specified value. This method 547: * supplies a general-purpose mechanism through which it is possible to set 548: * the various parameters of this object. A parameter may be any settable 549: * parameter for the algorithm, such as a parameter size, or a source of 550: * random bits for signature generation (if appropriate), or an indication of 551: * whether or not to perform a specific but optional computation. A uniform 552: * algorithm-specific naming scheme for each parameter is desirable but left 553: * unspecified at this time. 554: * 555: * @param param the string identifier of the parameter. 556: * @param value the parameter value. 557: * @throws InvalidParameterException if param is an invalid parameter for this 558: * signature algorithm engine, the parameter is already set and cannot be set 559: * again, a security exception occurs, and so on. 560: * @see #getParameter(String) 561: * @deprecated Use setParameter(AlgorithmParameterSpec). 562: */ 563: public final void setParameter(String param, Object value) 564: throws InvalidParameterException 565: { 566: engineSetParameter(param, value); 567: } 568: 569: /** 570: * Initializes this signature engine with the specified parameter set. 571: * 572: * @param params the parameters. 573: * @throws InvalidAlgorithmParameterException if the given parameters are 574: * inappropriate for this signature engine. 575: * @see #getParameters() 576: */ 577: public final void setParameter(AlgorithmParameterSpec params) 578: throws InvalidAlgorithmParameterException 579: { 580: engineSetParameter(params); 581: } 582: 583: /** 584: * <p>Returns the parameters used with this signature object.</p> 585: * 586: * <p>The returned parameters may be the same that were used to initialize 587: * this signature, or may contain a combination of default and randomly 588: * generated parameter values used by the underlying signature implementation 589: * if this signature requires algorithm parameters but was not initialized 590: * with any. 591: * 592: * @return the parameters used with this signature, or <code>null</code> if 593: * this signature does not use any parameters. 594: * @see #setParameter(AlgorithmParameterSpec) 595: */ 596: public final AlgorithmParameters getParameters() 597: { 598: return engineGetParameters(); 599: } 600: 601: /** 602: * Gets the value of the specified algorithm parameter. This method supplies 603: * a general-purpose mechanism through which it is possible to get the various 604: * parameters of this object. A parameter may be any settable parameter for 605: * the algorithm, such as a parameter size, or a source of random bits for 606: * signature generation (if appropriate), or an indication of whether or not 607: * to perform a specific but optional computation. A uniform 608: * algorithm-specific naming scheme for each parameter is desirable but left 609: * unspecified at this time. 610: * 611: * @param param the string name of the parameter. 612: * @return the object that represents the parameter value, or null if there 613: * is none. 614: * @throws InvalidParameterException if param is an invalid parameter for this 615: * engine, or another exception occurs while trying to get this parameter. 616: * @see #setParameter(String, Object) 617: * @deprecated 618: */ 619: public final Object getParameter(String param) 620: throws InvalidParameterException 621: { 622: return engineGetParameter(param); 623: } 624: 625: /** 626: * Returns a clone if the implementation is cloneable. 627: * 628: * @return a clone if the implementation is cloneable. 629: * @throws CloneNotSupportedException if this is called on an implementation 630: * that does not support {@link Cloneable}. 631: */ 632: public Object clone() throws CloneNotSupportedException 633: { 634: return super.clone(); 635: } 636: }
GNU Classpath (0.20) |