1. /*
  2. * @(#)SignatureSpi.java 1.24 04/05/18
  3. *
  4. * Copyright 2004 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.nio.ByteBuffer;
  12. import sun.security.jca.JCAUtil;
  13. /**
  14. * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
  15. * for the <code>Signature</code> class, which is used to provide the
  16. * functionality of a digital signature algorithm. Digital signatures are used
  17. * for authentication and integrity assurance of digital data.
  18. *.
  19. * <p> All the abstract methods in this class must be implemented by each
  20. * cryptographic service provider who wishes to supply the implementation
  21. * of a particular signature algorithm.
  22. *
  23. * @author Benjamin Renaud
  24. *
  25. * @version 1.24, 05/18/04
  26. *
  27. * @see Signature
  28. */
  29. public abstract class SignatureSpi {
  30. /**
  31. * Application-specified source of randomness.
  32. */
  33. protected SecureRandom appRandom = null;
  34. /**
  35. * Initializes this signature object with the specified
  36. * public key for verification operations.
  37. *
  38. * @param publicKey the public key of the identity whose signature is
  39. * going to be verified.
  40. *
  41. * @exception InvalidKeyException if the key is improperly
  42. * encoded, parameters are missing, and so on.
  43. */
  44. protected abstract void engineInitVerify(PublicKey publicKey)
  45. throws InvalidKeyException;
  46. /**
  47. * Initializes this signature object with the specified
  48. * private key for signing operations.
  49. *
  50. * @param privateKey the private key of the identity whose signature
  51. * will be generated.
  52. *
  53. * @exception InvalidKeyException if the key is improperly
  54. * encoded, parameters are missing, and so on.
  55. */
  56. protected abstract void engineInitSign(PrivateKey privateKey)
  57. throws InvalidKeyException;
  58. /**
  59. * Initializes this signature object with the specified
  60. * private key and source of randomness for signing operations.
  61. *
  62. * <p>This concrete method has been added to this previously-defined
  63. * abstract class. (For backwards compatibility, it cannot be abstract.)
  64. *
  65. * @param privateKey the private key of the identity whose signature
  66. * will be generated.
  67. * @param random the source of randomness
  68. *
  69. * @exception InvalidKeyException if the key is improperly
  70. * encoded, parameters are missing, and so on.
  71. */
  72. protected void engineInitSign(PrivateKey privateKey,
  73. SecureRandom random)
  74. throws InvalidKeyException {
  75. this.appRandom = random;
  76. engineInitSign(privateKey);
  77. }
  78. /**
  79. * Updates the data to be signed or verified
  80. * using the specified byte.
  81. *
  82. * @param b the byte to use for the update.
  83. *
  84. * @exception SignatureException if the engine is not initialized
  85. * properly.
  86. */
  87. protected abstract void engineUpdate(byte b) throws SignatureException;
  88. /**
  89. * Updates the data to be signed or verified, using the
  90. * specified array of bytes, starting at the specified offset.
  91. *
  92. * @param b the array of bytes
  93. * @param off the offset to start from in the array of bytes
  94. * @param len the number of bytes to use, starting at offset
  95. *
  96. * @exception SignatureException if the engine is not initialized
  97. * properly
  98. */
  99. protected abstract void engineUpdate(byte[] b, int off, int len)
  100. throws SignatureException;
  101. /**
  102. * Updates the data to be signed or verified using the specified
  103. * ByteBuffer. Processes the <code>data.remaining()</code> bytes
  104. * starting at at <code>data.position()</code>.
  105. * Upon return, the buffer's position will be equal to its limit;
  106. * its limit will not have changed.
  107. *
  108. * @param input the ByteBuffer
  109. * @since 1.5
  110. */
  111. protected void engineUpdate(ByteBuffer input) {
  112. if (input.hasRemaining() == false) {
  113. return;
  114. }
  115. try {
  116. if (input.hasArray()) {
  117. byte[] b = input.array();
  118. int ofs = input.arrayOffset();
  119. int pos = input.position();
  120. int lim = input.limit();
  121. engineUpdate(b, ofs + pos, lim - pos);
  122. input.position(lim);
  123. } else {
  124. int len = input.remaining();
  125. byte[] b = new byte[JCAUtil.getTempArraySize(len)];
  126. while (len > 0) {
  127. int chunk = Math.min(len, b.length);
  128. input.get(b, 0, chunk);
  129. engineUpdate(b, 0, chunk);
  130. len -= chunk;
  131. }
  132. }
  133. } catch (SignatureException e) {
  134. // is specified to only occur when the engine is not initialized
  135. // this case should never occur as it is caught in Signature.java
  136. throw new ProviderException("update() failed", e);
  137. }
  138. }
  139. /**
  140. * Returns the signature bytes of all the data
  141. * updated so far.
  142. * The format of the signature depends on the underlying
  143. * signature scheme.
  144. *
  145. * @return the signature bytes of the signing operation's result.
  146. *
  147. * @exception SignatureException if the engine is not
  148. * initialized properly or if this signature algorithm is unable to
  149. * process the input data provided.
  150. */
  151. protected abstract byte[] engineSign() throws SignatureException;
  152. /**
  153. * Finishes this signature operation and stores the resulting signature
  154. * bytes in the provided buffer <code>outbuf</code>, starting at
  155. * <code>offset</code>.
  156. * The format of the signature depends on the underlying
  157. * signature scheme.
  158. *
  159. * <p>The signature implementation is reset to its initial state
  160. * (the state it was in after a call to one of the
  161. * <code>engineInitSign</code> methods)
  162. * and can be reused to generate further signatures with the same private
  163. * key.
  164. *
  165. * This method should be abstract, but we leave it concrete for
  166. * binary compatibility. Knowledgeable providers should override this
  167. * method.
  168. *
  169. * @param outbuf buffer for the signature result.
  170. *
  171. * @param offset offset into <code>outbuf</code> where the signature is
  172. * stored.
  173. *
  174. * @param len number of bytes within <code>outbuf</code> allotted for the
  175. * signature.
  176. * Both this default implementation and the SUN provider do not
  177. * return partial digests. If the value of this parameter is less
  178. * than the actual signature length, this method will throw a
  179. * SignatureException.
  180. * This parameter is ignored if its value is greater than or equal to
  181. * the actual signature length.
  182. *
  183. * @return the number of bytes placed into <code>outbuf</code>
  184. *
  185. * @exception SignatureException if the engine is not
  186. * initialized properly, if this signature algorithm is unable to
  187. * process the input data provided, or if <code>len</code> is less
  188. * than the actual signature length.
  189. *
  190. * @since 1.2
  191. */
  192. protected int engineSign(byte[] outbuf, int offset, int len)
  193. throws SignatureException {
  194. byte[] sig = engineSign();
  195. if (len < sig.length) {
  196. throw new SignatureException
  197. ("partial signatures not returned");
  198. }
  199. if (outbuf.length - offset < sig.length) {
  200. throw new SignatureException
  201. ("insufficient space in the output buffer to store the "
  202. + "signature");
  203. }
  204. System.arraycopy(sig, 0, outbuf, offset, sig.length);
  205. return sig.length;
  206. }
  207. /**
  208. * Verifies the passed-in signature.
  209. *
  210. * @param sigBytes the signature bytes to be verified.
  211. *
  212. * @return true if the signature was verified, false if not.
  213. *
  214. * @exception SignatureException if the engine is not
  215. * initialized properly, the passed-in signature is improperly
  216. * encoded or of the wrong type, if this signature algorithm is unable to
  217. * process the input data provided, etc.
  218. */
  219. protected abstract boolean engineVerify(byte[] sigBytes)
  220. throws SignatureException;
  221. /**
  222. * Verifies the passed-in signature in the specified array
  223. * of bytes, starting at the specified offset.
  224. *
  225. * <p> Note: Subclasses should overwrite the default implementation.
  226. *
  227. *
  228. * @param sigBytes the signature bytes to be verified.
  229. * @param offset the offset to start from in the array of bytes.
  230. * @param length the number of bytes to use, starting at offset.
  231. *
  232. * @return true if the signature was verified, false if not.
  233. *
  234. * @exception SignatureException if the engine is not
  235. * initialized properly, the passed-in signature is improperly
  236. * encoded or of the wrong type, if this signature algorithm is unable to
  237. * process the input data provided, etc.
  238. */
  239. protected boolean engineVerify(byte[] sigBytes, int offset, int length)
  240. throws SignatureException {
  241. byte[] sigBytesCopy = new byte[length];
  242. System.arraycopy(sigBytes, offset, sigBytesCopy, 0, length);
  243. return engineVerify(sigBytesCopy);
  244. }
  245. /**
  246. * Sets the specified algorithm parameter to the specified
  247. * value. This method supplies a general-purpose mechanism through
  248. * which it is possible to set the various parameters of this object.
  249. * A parameter may be any settable parameter for the algorithm, such as
  250. * a parameter size, or a source of random bits for signature generation
  251. * (if appropriate), or an indication of whether or not to perform
  252. * a specific but optional computation. A uniform algorithm-specific
  253. * naming scheme for each parameter is desirable but left unspecified
  254. * at this time.
  255. *
  256. * @param param the string identifier of the parameter.
  257. *
  258. * @param value the parameter value.
  259. *
  260. * @exception InvalidParameterException if <code>param</code> is an
  261. * invalid parameter for this signature algorithm engine,
  262. * the parameter is already set
  263. * and cannot be set again, a security exception occurs, and so on.
  264. *
  265. * @deprecated Replaced by {@link
  266. * #engineSetParameter(java.security.spec.AlgorithmParameterSpec)
  267. * engineSetParameter}.
  268. */
  269. @Deprecated
  270. protected abstract void engineSetParameter(String param, Object value)
  271. throws InvalidParameterException;
  272. /**
  273. * <p>This method is overridden by providers to initialize
  274. * this signature engine with the specified parameter set.
  275. *
  276. * @param params the parameters
  277. *
  278. * @exception UnsupportedOperationException if this method is not
  279. * overridden by a provider
  280. *
  281. * @exception InvalidAlgorithmParameterException if this method is
  282. * overridden by a provider and the the given parameters
  283. * are inappropriate for this signature engine
  284. */
  285. protected void engineSetParameter(AlgorithmParameterSpec params)
  286. throws InvalidAlgorithmParameterException {
  287. throw new UnsupportedOperationException();
  288. }
  289. /**
  290. * <p>This method is overridden by providers to return the
  291. * parameters used with this signature engine, or null
  292. * if this signature engine does not use any parameters.
  293. *
  294. * <p>The returned parameters may be the same that were used to initialize
  295. * this signature engine, or may contain a combination of default and
  296. * randomly generated parameter values used by the underlying signature
  297. * implementation if this signature engine requires algorithm parameters
  298. * but was not initialized with any.
  299. *
  300. * @return the parameters used with this signature engine, or null if this
  301. * signature engine does not use any parameters
  302. *
  303. * @exception UnsupportedOperationException if this method is
  304. * not overridden by a provider
  305. */
  306. protected AlgorithmParameters engineGetParameters() {
  307. throw new UnsupportedOperationException();
  308. }
  309. /**
  310. * Gets the value of the specified algorithm parameter.
  311. * This method supplies a general-purpose mechanism through which it
  312. * is possible to get the various parameters of this object. A parameter
  313. * may be any settable parameter for the algorithm, such as a parameter
  314. * size, or a source of random bits for signature generation (if
  315. * appropriate), or an indication of whether or not to perform a
  316. * specific but optional computation. A uniform algorithm-specific
  317. * naming scheme for each parameter is desirable but left unspecified
  318. * at this time.
  319. *
  320. * @param param the string name of the parameter.
  321. *
  322. * @return the object that represents the parameter value, or null if
  323. * there is none.
  324. *
  325. * @exception InvalidParameterException if <code>param</code> is an
  326. * invalid parameter for this engine, or another exception occurs while
  327. * trying to get this parameter.
  328. *
  329. * @deprecated
  330. */
  331. @Deprecated
  332. protected abstract Object engineGetParameter(String param)
  333. throws InvalidParameterException;
  334. /**
  335. * Returns a clone if the implementation is cloneable.
  336. *
  337. * @return a clone if the implementation is cloneable.
  338. *
  339. * @exception CloneNotSupportedException if this is called
  340. * on an implementation that does not support <code>Cloneable</code>.
  341. */
  342. public Object clone() throws CloneNotSupportedException {
  343. if (this instanceof Cloneable) {
  344. return super.clone();
  345. } else {
  346. throw new CloneNotSupportedException();
  347. }
  348. }
  349. }