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