1. /*
  2. * @(#)Signature.java 1.91 03/01/23
  3. *
  4. * Copyright 2003 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. import java.security.cert.Certificate;
  12. import java.security.cert.X509Certificate;
  13. /**
  14. * This Signature class is used to provide applications the functionality
  15. * of a digital signature algorithm. Digital signatures are used for
  16. * authentication and integrity assurance of digital data.
  17. *
  18. * <p> The signature algorithm can be, among others, the NIST standard
  19. * DSA, using DSA and SHA-1. The DSA algorithm using the
  20. * SHA-1 message digest algorithm can be specified as <tt>SHA1withDSA</tt>.
  21. * In the case of RSA, there are multiple choices for the message digest
  22. * algorithm, so the signing algorithm could be specified as, for example,
  23. * <tt>MD2withRSA</tt>, <tt>MD5withRSA</tt>, or <tt>SHA1withRSA</tt>.
  24. * The algorithm name must be specified, as there is no default.
  25. *
  26. * <p>Like other algorithm-based classes in Java Security, Signature
  27. * provides implementation-independent algorithms, whereby a caller
  28. * (application code) requests a particular signature algorithm
  29. * and is handed back a properly initialized Signature object. It is
  30. * also possible, if desired, to request a particular algorithm from a
  31. * particular provider. See the <code>getInstance </code> methods.
  32. *
  33. * <p>Thus, there are two ways to request a Signature algorithm object: by
  34. * specifying either just an algorithm name, or both an algorithm name
  35. * and a package provider. <ul>
  36. *
  37. * <li>If just an algorithm name is specified, the system will
  38. * determine if there is an implementation of the algorithm requested
  39. * available in the environment, and if there is more than one, if
  40. * there is a preferred one.<p>
  41. *
  42. * <li>If both an algorithm name and a package provider are specified,
  43. * the system will determine if there is an implementation of the
  44. * algorithm in the package requested, and throw an exception if there
  45. * is not.
  46. *
  47. * </ul>
  48. *
  49. * <p>A Signature object can be used to generate and verify digital
  50. * signatures.
  51. *
  52. * <p>There are three phases to the use of a Signature object for
  53. * either signing data or verifying a signature:<ol>
  54. *
  55. * <li>Initialization, with either
  56. *
  57. * <ul>
  58. *
  59. * <li>a public key, which initializes the signature for
  60. * verification (see {@link #initVerify(PublicKey) initVerify}), or
  61. *
  62. * <li>a private key (and optionally a Secure Random Number Generator),
  63. * which initializes the signature for signing
  64. * (see {@link #initSign(PrivateKey)}
  65. * and {@link #initSign(PrivateKey, SecureRandom)}).
  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.91, 01/23/03
  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 {@link #state} value, signifying that
  105. * this signature object has not yet been initialized.
  106. */
  107. protected final static int UNINITIALIZED = 0;
  108. /**
  109. * Possible {@link #state} value, signifying that
  110. * this signature object has been initialized for signing.
  111. */
  112. protected final static int SIGN = 2;
  113. /**
  114. * Possible {@link #state} 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. try {
  156. Object[] objs = Security.getImpl(algorithm, "Signature",
  157. (String)null);
  158. if (objs[0] instanceof Signature) {
  159. Signature sig = (Signature)objs[0];
  160. sig.provider = (Provider)objs[1];
  161. return sig;
  162. } else {
  163. Signature delegate =
  164. new Delegate((SignatureSpi)objs[0], algorithm);
  165. delegate.provider = (Provider)objs[1];
  166. return delegate;
  167. }
  168. } catch(NoSuchProviderException e) {
  169. throw new NoSuchAlgorithmException(algorithm + " not found");
  170. }
  171. }
  172. /**
  173. * Generates a Signature object implementing the specified
  174. * algorithm, as supplied from the specified provider, if such an
  175. * algorithm is available from the provider.
  176. *
  177. * @param algorithm the name of the algorithm requested.
  178. * See Appendix A in the <a href=
  179. * "../../../guide/security/CryptoSpec.html#AppA">
  180. * Java Cryptography Architecture API Specification & Reference </a>
  181. * for information about standard algorithm names.
  182. *
  183. * @param provider the name of the provider.
  184. *
  185. * @return the new Signature object.
  186. *
  187. * @exception NoSuchAlgorithmException if the algorithm is
  188. * not available in the package supplied by the requested
  189. * provider.
  190. *
  191. * @exception NoSuchProviderException if the provider is not
  192. * available in the environment.
  193. *
  194. * @exception IllegalArgumentException if the provider name is null
  195. * or empty.
  196. *
  197. * @see Provider
  198. */
  199. public static Signature getInstance(String algorithm, String provider)
  200. throws NoSuchAlgorithmException, NoSuchProviderException
  201. {
  202. if (provider == null || provider.length() == 0)
  203. throw new IllegalArgumentException("missing provider");
  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. * Generates a Signature object implementing the specified
  218. * algorithm, as supplied from the specified provider, if such an
  219. * algorithm is available from the provider. Note: the
  220. * <code>provider</code> doesn't have to be registered.
  221. *
  222. * @param algorithm the name of the algorithm requested.
  223. * See Appendix A in the <a href=
  224. * "../../../guide/security/CryptoSpec.html#AppA">
  225. * Java Cryptography Architecture API Specification & Reference </a>
  226. * for information about standard algorithm names.
  227. *
  228. * @param provider the provider.
  229. *
  230. * @return the new Signature object.
  231. *
  232. * @exception NoSuchAlgorithmException if the algorithm is
  233. * not available in the package supplied by the requested
  234. * provider.
  235. *
  236. * @exception IllegalArgumentException if the <code>provider</code> is
  237. * null.
  238. *
  239. * @see Provider
  240. *
  241. * @since 1.4
  242. */
  243. public static Signature getInstance(String algorithm, Provider provider)
  244. throws NoSuchAlgorithmException
  245. {
  246. if (provider == null)
  247. throw new IllegalArgumentException("missing provider");
  248. Object[] objs = Security.getImpl(algorithm, "Signature", provider);
  249. if (objs[0] instanceof Signature) {
  250. Signature sig = (Signature)objs[0];
  251. sig.provider = (Provider)objs[1];
  252. return sig;
  253. } else {
  254. Signature delegate =
  255. new Delegate((SignatureSpi)objs[0], algorithm);
  256. delegate.provider = (Provider)objs[1];
  257. return delegate;
  258. }
  259. }
  260. /**
  261. * Returns the provider of this signature object.
  262. *
  263. * @return the provider of this signature object
  264. */
  265. public final Provider getProvider() {
  266. return this.provider;
  267. }
  268. /**
  269. * Initializes this object for verification. If this method is called
  270. * again with a different argument, it negates the effect
  271. * of this call.
  272. *
  273. * @param publicKey the public key of the identity whose signature is
  274. * going to be verified.
  275. *
  276. * @exception InvalidKeyException if the key is invalid.
  277. */
  278. public final void initVerify(PublicKey publicKey)
  279. throws InvalidKeyException {
  280. engineInitVerify(publicKey);
  281. state = VERIFY;
  282. }
  283. /**
  284. * Initializes this object for verification, using the public key from
  285. * the given certificate.
  286. * <p>If the certificate is of type X.509 and has a <i>key usage</i>
  287. * extension field marked as critical, and the value of the <i>key usage</i>
  288. * extension field implies that the public key in
  289. * the certificate and its corresponding private key are not
  290. * supposed to be used for digital signatures, an <code>InvalidKeyException</code>
  291. * is thrown.
  292. *
  293. * @param certificate the certificate of the identity whose signature is
  294. * going to be verified.
  295. *
  296. * @exception InvalidKeyException if the public key in the certificate
  297. * is not encoded properly or does not include required parameter
  298. * information or cannot be used for digital signature purposes.
  299. */
  300. public final void initVerify(Certificate certificate)
  301. throws InvalidKeyException {
  302. // If the certificate is of type X509Certificate,
  303. // we should check whether it has a Key Usage
  304. // extension marked as critical.
  305. if (certificate instanceof java.security.cert.X509Certificate) {
  306. // Check whether the cert has a key usage extension
  307. // marked as a critical extension.
  308. // The OID for KeyUsage extension is 2.5.29.15.
  309. X509Certificate cert = (X509Certificate)certificate;
  310. Set critSet = cert.getCriticalExtensionOIDs();
  311. if (critSet != null && !critSet.isEmpty()
  312. && critSet.contains(new String("2.5.29.15"))) {
  313. boolean[] keyUsageInfo = cert.getKeyUsage();
  314. // keyUsageInfo[0] is for digitalSignature.
  315. if ((keyUsageInfo != null) && (keyUsageInfo[0] == false))
  316. throw new InvalidKeyException("Wrong key usage");
  317. }
  318. }
  319. PublicKey publicKey = certificate.getPublicKey();
  320. engineInitVerify(publicKey);
  321. state = VERIFY;
  322. }
  323. /**
  324. * Initialize this object for signing. If this method is called
  325. * again with a different argument, it negates the effect
  326. * of this call.
  327. *
  328. * @param privateKey the private key of the identity whose signature
  329. * is going to be generated.
  330. *
  331. * @exception InvalidKeyException if the key is invalid.
  332. */
  333. public final void initSign(PrivateKey privateKey)
  334. throws InvalidKeyException {
  335. engineInitSign(privateKey);
  336. state = SIGN;
  337. }
  338. /**
  339. * Initialize this object for signing. If this method is called
  340. * again with a different argument, it negates the effect
  341. * of this call.
  342. *
  343. * @param privateKey the private key of the identity whose signature
  344. * is going to be generated.
  345. *
  346. * @param random the source of randomness for this signature.
  347. *
  348. * @exception InvalidKeyException if the key is invalid.
  349. */
  350. public final void initSign(PrivateKey privateKey, SecureRandom random)
  351. throws InvalidKeyException {
  352. engineInitSign(privateKey, random);
  353. state = SIGN;
  354. }
  355. /**
  356. * Returns the signature bytes of all the data updated.
  357. * The format of the signature depends on the underlying
  358. * signature scheme.
  359. *
  360. * <p>A call to this method resets this signature object to the state
  361. * it was in when previously initialized for signing via a
  362. * call to <code>initSign(PrivateKey)</code>. That is, the object is
  363. * reset and available to generate another signature from the same
  364. * signer, if desired, via new calls to <code>update</code> and
  365. * <code>sign</code>.
  366. *
  367. * @return the signature bytes of the signing operation's result.
  368. *
  369. * @exception SignatureException if this signature object is not
  370. * initialized properly.
  371. */
  372. public final byte[] sign() throws SignatureException {
  373. if (state == SIGN) {
  374. return engineSign();
  375. }
  376. throw new SignatureException("object not initialized for " +
  377. "signing");
  378. }
  379. /**
  380. * Finishes the signature operation and stores the resulting signature
  381. * bytes in the provided buffer <code>outbuf</code>, starting at
  382. * <code>offset</code>.
  383. * The format of the signature depends on the underlying
  384. * signature scheme.
  385. *
  386. * <p>This signature object is reset to its initial state (the state it
  387. * was in after a call to one of the <code>initSign</code> methods) and
  388. * can be reused to generate further signatures with the same private key.
  389. *
  390. * @param outbuf buffer for the signature result.
  391. *
  392. * @param offset offset into <code>outbuf</code> where the signature is
  393. * stored.
  394. *
  395. * @param len number of bytes within <code>outbuf</code> allotted for the
  396. * signature.
  397. *
  398. * @return the number of bytes placed into <code>outbuf</code>.
  399. *
  400. * @exception SignatureException if an error occurs or <code>len</code>
  401. * is less than the actual signature length.
  402. *
  403. * @since 1.2
  404. */
  405. public final int sign(byte[] outbuf, int offset, int len)
  406. throws SignatureException {
  407. if (outbuf == null) {
  408. throw new IllegalArgumentException("No output buffer given");
  409. }
  410. if (outbuf.length - offset < len) {
  411. throw new IllegalArgumentException
  412. ("Output buffer too small for specified offset and length");
  413. }
  414. if (state != SIGN) {
  415. throw new SignatureException("object not initialized for " +
  416. "signing");
  417. }
  418. return engineSign(outbuf, offset, len);
  419. }
  420. /**
  421. * Verifies the passed-in signature.
  422. *
  423. * <p>A call to this method resets this signature object to the state
  424. * it was in when previously initialized for verification via a
  425. * call to <code>initVerify(PublicKey)</code>. That is, the object is
  426. * reset and available to verify another signature from the identity
  427. * whose public key was specified in the call to <code>initVerify</code>.
  428. *
  429. * @param signature the signature bytes to be verified.
  430. *
  431. * @return true if the signature was verified, false if not.
  432. *
  433. * @exception SignatureException if this signature object is not
  434. * initialized properly, or the passed-in signature is improperly
  435. * encoded or of the wrong type, etc.
  436. */
  437. public final boolean verify(byte[] signature) throws SignatureException {
  438. if (state == VERIFY) {
  439. return engineVerify(signature);
  440. }
  441. throw new SignatureException("object not initialized for " +
  442. "verification");
  443. }
  444. /**
  445. * Verifies the passed-in signature in the specified array
  446. * of bytes, starting at the specified offset.
  447. *
  448. * <p>A call to this method resets this signature object to the state
  449. * it was in when previously initialized for verification via a
  450. * call to <code>initVerify(PublicKey)</code>. That is, the object is
  451. * reset and available to verify another signature from the identity
  452. * whose public key was specified in the call to <code>initVerify</code>.
  453. *
  454. *
  455. * @param signature the signature bytes to be verified.
  456. * @param offset the offset to start from in the array of bytes.
  457. * @param length the number of bytes to use, starting at offset.
  458. *
  459. * @return true if the signature was verified, false if not.
  460. *
  461. * @exception SignatureException if this signature object is not
  462. * initialized properly, or the passed-in signature is improperly
  463. * encoded or of the wrong type, etc.
  464. * @exception IllegalArgumentException if the <code>signature</code>
  465. * byte array is null, or the <code>offset</code> or <code>length</code>
  466. * is less than 0, or the sum of the <code>offset</code> and
  467. * <code>length</code> is greater than the length of the
  468. * <code>signature</code> byte array.
  469. */
  470. public final boolean verify(byte[] signature, int offset, int length)
  471. throws SignatureException {
  472. if (state == VERIFY) {
  473. if ((signature == null) || (offset < 0) || (length < 0) ||
  474. (offset + length > signature.length)) {
  475. throw new IllegalArgumentException("Bad arguments");
  476. }
  477. return engineVerify(signature, offset, length);
  478. }
  479. throw new SignatureException("object not initialized for " +
  480. "verification");
  481. }
  482. /**
  483. * Updates the data to be signed or verified by a byte.
  484. *
  485. * @param b the byte to use for the update.
  486. *
  487. * @exception SignatureException if this signature object is not
  488. * initialized properly.
  489. */
  490. public final void update(byte b) throws SignatureException {
  491. if (state == VERIFY || state == SIGN) {
  492. engineUpdate(b);
  493. } else {
  494. throw new SignatureException("object not initialized for "
  495. + "signature or verification");
  496. }
  497. }
  498. /**
  499. * Updates the data to be signed or verified, using the specified
  500. * array of bytes.
  501. *
  502. * @param data the byte array to use for the update.
  503. *
  504. * @exception SignatureException if this signature object is not
  505. * initialized properly.
  506. */
  507. public final void update(byte[] data) throws SignatureException {
  508. update(data, 0, data.length);
  509. }
  510. /**
  511. * Updates the data to be signed or verified, using the specified
  512. * array of bytes, starting at the specified offset.
  513. *
  514. * @param data the array of bytes.
  515. * @param off the offset to start from in the array of bytes.
  516. * @param len the number of bytes to use, starting at offset.
  517. *
  518. * @exception SignatureException if this signature object is not
  519. * initialized properly.
  520. */
  521. public final void update(byte[] data, int off, int len)
  522. throws SignatureException {
  523. if (state == SIGN || state == VERIFY) {
  524. engineUpdate(data, off, len);
  525. } else {
  526. throw new SignatureException("object not initialized for "
  527. + "signature or verification");
  528. }
  529. }
  530. /**
  531. * Returns the name of the algorithm for this signature object.
  532. *
  533. * @return the name of the algorithm for this signature object.
  534. */
  535. public final String getAlgorithm() {
  536. return this.algorithm;
  537. }
  538. /**
  539. * Returns a string representation of this signature object,
  540. * providing information that includes the state of the object
  541. * and the name of the algorithm used.
  542. *
  543. * @return a string representation of this signature object.
  544. */
  545. public String toString() {
  546. String initState = "";
  547. switch (state) {
  548. case UNINITIALIZED:
  549. initState = "<not initialized>";
  550. break;
  551. case VERIFY:
  552. initState = "<initialized for verifying>";
  553. break;
  554. case SIGN:
  555. initState = "<initialized for signing>";
  556. break;
  557. }
  558. return "Signature object: " + getAlgorithm() + initState;
  559. }
  560. /**
  561. * Sets the specified algorithm parameter to the specified value.
  562. * This method supplies a general-purpose mechanism through
  563. * which it is possible to set the various parameters of this object.
  564. * A parameter may be any settable parameter for the algorithm, such as
  565. * a parameter size, or a source of random bits for signature generation
  566. * (if appropriate), or an indication of whether or not to perform
  567. * a specific but optional computation. A uniform algorithm-specific
  568. * naming scheme for each parameter is desirable but left unspecified
  569. * at this time.
  570. *
  571. * @param param the string identifier of the parameter.
  572. * @param value the parameter value.
  573. *
  574. * @exception InvalidParameterException if <code>param</code> is an
  575. * invalid parameter for this signature algorithm engine,
  576. * the parameter is already set
  577. * and cannot be set again, a security exception occurs, and so on.
  578. *
  579. * @see #getParameter
  580. *
  581. * @deprecated Use
  582. * {@link #setParameter(java.security.spec.AlgorithmParameterSpec)
  583. * setParameter}.
  584. */
  585. public final void setParameter(String param, Object value)
  586. throws InvalidParameterException {
  587. engineSetParameter(param, value);
  588. }
  589. /**
  590. * Initializes this signature engine with the specified parameter set.
  591. *
  592. * @param params the parameters
  593. *
  594. * @exception InvalidAlgorithmParameterException if the given parameters
  595. * are inappropriate for this signature engine
  596. *
  597. * @see #getParameters
  598. */
  599. public final void setParameter(AlgorithmParameterSpec params)
  600. throws InvalidAlgorithmParameterException {
  601. engineSetParameter(params);
  602. }
  603. /**
  604. * Returns the parameters used with this signature object.
  605. *
  606. * <p>The returned parameters may be the same that were used to initialize
  607. * this signature, or may contain a combination of default and randomly
  608. * generated parameter values used by the underlying signature
  609. * implementation if this signature requires algorithm parameters but
  610. * was not initialized with any.
  611. *
  612. * @return the parameters used with this signature, or null if this
  613. * signature does not use any parameters.
  614. *
  615. * @see #setParameter(AlgorithmParameterSpec)
  616. */
  617. public final AlgorithmParameters getParameters() {
  618. return engineGetParameters();
  619. }
  620. /**
  621. * Gets the value of the specified algorithm parameter. This method
  622. * supplies a general-purpose mechanism through which it is possible to
  623. * get the various parameters of this object. A parameter may be any
  624. * settable parameter for the algorithm, such as a parameter size, or
  625. * a source of random bits for signature generation (if appropriate),
  626. * or an indication of whether or not to perform a specific but optional
  627. * computation. A uniform algorithm-specific naming scheme for each
  628. * parameter is desirable but left unspecified at this time.
  629. *
  630. * @param param the string name of the parameter.
  631. *
  632. * @return the object that represents the parameter value, or null if
  633. * there is none.
  634. *
  635. * @exception InvalidParameterException if <code>param</code> is an invalid
  636. * parameter for this engine, or another exception occurs while
  637. * trying to get this parameter.
  638. *
  639. * @see #setParameter(String, Object)
  640. *
  641. * @deprecated
  642. */
  643. public final Object getParameter(String param)
  644. throws InvalidParameterException {
  645. return engineGetParameter(param);
  646. }
  647. /**
  648. * Returns a clone if the implementation is cloneable.
  649. *
  650. * @return a clone if the implementation is cloneable.
  651. *
  652. * @exception CloneNotSupportedException if this is called
  653. * on an implementation that does not support <code>Cloneable</code>.
  654. */
  655. public Object clone() throws CloneNotSupportedException {
  656. if (this instanceof Cloneable) {
  657. return super.clone();
  658. } else {
  659. throw new CloneNotSupportedException();
  660. }
  661. }
  662. // private debugging method.
  663. private static void debug(String statement) {
  664. if (debug) {
  665. System.err.println(statement);
  666. }
  667. }
  668. // private debugging method.
  669. private static void debug(Exception e) {
  670. if (debug) {
  671. e.printStackTrace();
  672. }
  673. }
  674. /*
  675. * The following class allows providers to extend from SignatureSpi
  676. * rather than from Signature. It represents a Signature with an
  677. * encapsulated, provider-supplied SPI object (of type SignatureSpi).
  678. * If the provider implementation is an instance of SignatureSpi, the
  679. * getInstance() methods above return an instance of this class, with
  680. * the SPI object encapsulated.
  681. *
  682. * Note: All SPI methods from the original Signature class have been
  683. * moved up the hierarchy into a new class (SignatureSpi), which has
  684. * been interposed in the hierarchy between the API (Signature)
  685. * and its original parent (Object).
  686. */
  687. static class Delegate extends Signature {
  688. // The provider implementation (delegate)
  689. private SignatureSpi sigSpi;
  690. // constructor
  691. public Delegate(SignatureSpi sigSpi, String algorithm) {
  692. super(algorithm);
  693. this.sigSpi = sigSpi;
  694. }
  695. /*
  696. * Returns a clone if the delegate is cloneable.
  697. *
  698. * @return a clone if the delegate is cloneable.
  699. *
  700. * @exception CloneNotSupportedException if this is called on a
  701. * delegate that does not support <code>Cloneable</code>.
  702. */
  703. public Object clone() throws CloneNotSupportedException {
  704. if (sigSpi instanceof Cloneable) {
  705. SignatureSpi sigSpiClone = (SignatureSpi)sigSpi.clone();
  706. // Because 'algorithm' and 'provider' are private
  707. // members of our supertype, we must perform a cast to
  708. // access them.
  709. Signature that =
  710. new Delegate(sigSpiClone, ((Signature)this).algorithm);
  711. that.provider = ((Signature)this).provider;
  712. return that;
  713. } else {
  714. throw new CloneNotSupportedException();
  715. }
  716. }
  717. protected void engineInitVerify(PublicKey publicKey)
  718. throws InvalidKeyException {
  719. sigSpi.engineInitVerify(publicKey);
  720. }
  721. protected void engineInitSign(PrivateKey privateKey)
  722. throws InvalidKeyException {
  723. sigSpi.engineInitSign(privateKey);
  724. }
  725. protected void engineInitSign(PrivateKey privateKey, SecureRandom sr)
  726. throws InvalidKeyException {
  727. sigSpi.engineInitSign(privateKey, sr);
  728. }
  729. protected void engineUpdate(byte b) throws SignatureException {
  730. sigSpi.engineUpdate(b);
  731. }
  732. protected void engineUpdate(byte[] b, int off, int len)
  733. throws SignatureException {
  734. sigSpi.engineUpdate(b, off, len);
  735. }
  736. protected byte[] engineSign() throws SignatureException {
  737. return sigSpi.engineSign();
  738. }
  739. protected int engineSign(byte[] outbuf, int offset, int len)
  740. throws SignatureException {
  741. return sigSpi.engineSign(outbuf, offset, len);
  742. }
  743. protected boolean engineVerify(byte[] sigBytes)
  744. throws SignatureException {
  745. return sigSpi.engineVerify(sigBytes);
  746. }
  747. protected boolean engineVerify(byte[] sigBytes, int offset, int length)
  748. throws SignatureException {
  749. return sigSpi.engineVerify(sigBytes, offset, length);
  750. }
  751. protected void engineSetParameter(String param, Object value)
  752. throws InvalidParameterException {
  753. sigSpi.engineSetParameter(param, value);
  754. }
  755. protected void engineSetParameter(AlgorithmParameterSpec params)
  756. throws InvalidAlgorithmParameterException {
  757. sigSpi.engineSetParameter(params);
  758. }
  759. protected Object engineGetParameter(String param)
  760. throws InvalidParameterException {
  761. return sigSpi.engineGetParameter(param);
  762. }
  763. protected AlgorithmParameters engineGetParameters() {
  764. return sigSpi.engineGetParameters();
  765. }
  766. }
  767. }