1. /*
  2. * @(#)MessageDigest.java 1.71 00/02/02
  3. *
  4. * Copyright 1996-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package java.security;
  11. import java.util.*;
  12. import java.lang.*;
  13. import java.io.IOException;
  14. import java.io.ByteArrayOutputStream;
  15. import java.io.PrintStream;
  16. import java.io.InputStream;
  17. import java.io.ByteArrayInputStream;
  18. /**
  19. * This MessageDigest class provides applications the functionality of a
  20. * message digest algorithm, such as MD5 or SHA.
  21. * Message digests are secure one-way hash functions that take arbitrary-sized
  22. * data and output a fixed-length hash value.
  23. *
  24. * <p>A MessageDigest object starts out initialized. The data is
  25. * processed through it using the {@link #update(byte) update}
  26. * methods. At any point {@link #reset() reset} can be called
  27. * to reset the digest. Once all the data to be updated has been
  28. * updated, one of the {@link #digest() digest} methods should
  29. * be called to complete the hash computation.
  30. *
  31. * <p>The <code>digest</code> method can be called once for a given number
  32. * of updates. After <code>digest</code> has been called, the MessageDigest
  33. * object is reset to its initialized state.
  34. *
  35. * <p>Implementations are free to implement the Cloneable interface.
  36. * Client applications can test cloneability by attempting cloning
  37. * and catching the CloneNotSupportedException: <p>
  38. *
  39. * <pre>
  40. * MessageDigest md = MessageDigest.getInstance("SHA");
  41. *
  42. * try {
  43. * md.update(toChapter1);
  44. * MessageDigest tc1 = md.clone();
  45. * byte[] toChapter1Digest = tc1.digest();
  46. * md.update(toChapter2);
  47. * ...etc.
  48. * } catch (CloneNotSupportedException cnse) {
  49. * throw new DigestException("couldn't make digest of partial content");
  50. * }
  51. * </pre>
  52. *
  53. * <p>Note that if a given implementation is not cloneable, it is
  54. * still possible to compute intermediate digests by instantiating
  55. * several instances, if the number of digests is known in advance.
  56. *
  57. * <p>Note that this class is abstract and extends from
  58. * <code>MessageDigestSpi</code> for historical reasons.
  59. * Application developers should only take notice of the methods defined in
  60. * this <code>MessageDigest</code> class; all the methods in
  61. * the superclass are intended for cryptographic service providers who wish to
  62. * supply their own implementations of message digest algorithms.
  63. *
  64. * @author Benjamin Renaud
  65. *
  66. * @version 1.71, 02/02/00
  67. *
  68. * @see DigestInputStream
  69. * @see DigestOutputStream
  70. */
  71. public abstract class MessageDigest extends MessageDigestSpi {
  72. private String algorithm;
  73. // The state of this digest
  74. private static final int INITIAL = 0;
  75. private static final int IN_PROGRESS = 1;
  76. private int state = INITIAL;
  77. // The provider
  78. private Provider provider;
  79. /**
  80. * Creates a message digest with the specified algorithm name.
  81. *
  82. * @param algorithm the standard name of the digest algorithm.
  83. * See Appendix A in the <a href=
  84. * "../../../guide/security/CryptoSpec.html#AppA">
  85. * Java Cryptography Architecture API Specification & Reference </a>
  86. * for information about standard algorithm names.
  87. */
  88. protected MessageDigest(String algorithm) {
  89. this.algorithm = algorithm;
  90. }
  91. /**
  92. * Generates a MessageDigest object that implements the specified digest
  93. * algorithm. If the default provider package
  94. * provides an implementation of the requested digest algorithm,
  95. * an instance of MessageDigest containing that implementation is returned.
  96. * If the algorithm is not available in the default
  97. * package, other packages are searched.
  98. *
  99. * @param algorithm the name of the algorithm requested.
  100. * See Appendix A in the <a href=
  101. * "../../../guide/security/CryptoSpec.html#AppA">
  102. * Java Cryptography Architecture API Specification & Reference </a>
  103. * for information about standard algorithm names.
  104. *
  105. * @return a Message Digest object implementing the specified
  106. * algorithm.
  107. *
  108. * @exception NoSuchAlgorithmException if the algorithm is
  109. * not available in the caller's environment.
  110. */
  111. public static MessageDigest getInstance(String algorithm)
  112. throws NoSuchAlgorithmException {
  113. try {
  114. Object[] objs = Security.getImpl(algorithm, "MessageDigest", null);
  115. if (objs[0] instanceof MessageDigest) {
  116. MessageDigest md = (MessageDigest)objs[0];
  117. md.provider = (Provider)objs[1];
  118. return md;
  119. } else {
  120. MessageDigest delegate =
  121. new Delegate((MessageDigestSpi)objs[0], algorithm);
  122. delegate.provider = (Provider)objs[1];
  123. return delegate;
  124. }
  125. } catch(NoSuchProviderException e) {
  126. throw new NoSuchAlgorithmException(algorithm + " not found");
  127. }
  128. }
  129. /**
  130. * Generates a MessageDigest object implementing the specified
  131. * algorithm, as supplied from the specified provider, if such an
  132. * algorithm is available from the provider.
  133. *
  134. * @param algorithm the name of the algorithm requested.
  135. * See Appendix A in the <a href=
  136. * "../../../guide/security/CryptoSpec.html#AppA">
  137. * Java Cryptography Architecture API Specification & Reference </a>
  138. * for information about standard algorithm names.
  139. *
  140. * @param provider the name of the provider.
  141. *
  142. * @return a Message Digest object implementing the specified
  143. * algorithm.
  144. *
  145. * @exception NoSuchAlgorithmException if the algorithm is
  146. * not available in the package supplied by the requested
  147. * provider.
  148. *
  149. * @exception NoSuchProviderException if the provider is not
  150. * available in the environment.
  151. *
  152. * @see Provider
  153. */
  154. public static MessageDigest getInstance(String algorithm, String provider)
  155. throws NoSuchAlgorithmException, NoSuchProviderException
  156. {
  157. if (provider == null || provider.length() == 0)
  158. throw new IllegalArgumentException("missing provider");
  159. Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider);
  160. if (objs[0] instanceof MessageDigest) {
  161. MessageDigest md = (MessageDigest)objs[0];
  162. md.provider = (Provider)objs[1];
  163. return md;
  164. } else {
  165. MessageDigest delegate =
  166. new Delegate((MessageDigestSpi)objs[0], algorithm);
  167. delegate.provider = (Provider)objs[1];
  168. return delegate;
  169. }
  170. }
  171. /**
  172. * Returns the provider of this message digest object.
  173. *
  174. * @return the provider of this message digest object
  175. */
  176. public final Provider getProvider() {
  177. return this.provider;
  178. }
  179. /**
  180. * Updates the digest using the specified byte.
  181. *
  182. * @param input the byte with which to update the digest.
  183. */
  184. public void update(byte input) {
  185. engineUpdate(input);
  186. state = IN_PROGRESS;
  187. }
  188. /**
  189. * Updates the digest using the specified array of bytes, starting
  190. * at the specified offset.
  191. *
  192. * @param input the array of bytes.
  193. *
  194. * @param offset the offset to start from in the array of bytes.
  195. *
  196. * @param len the number of bytes to use, starting at
  197. * <code>offset</code>.
  198. */
  199. public void update(byte[] input, int offset, int len) {
  200. if (input == null) {
  201. throw new IllegalArgumentException("No input buffer given");
  202. }
  203. if (input.length - offset < len) {
  204. throw new IllegalArgumentException("Input buffer too short");
  205. }
  206. engineUpdate(input, offset, len);
  207. state = IN_PROGRESS;
  208. }
  209. /**
  210. * Updates the digest using the specified array of bytes.
  211. *
  212. * @param input the array of bytes.
  213. */
  214. public void update(byte[] input) {
  215. engineUpdate(input, 0, input.length);
  216. state = IN_PROGRESS;
  217. }
  218. /**
  219. * Completes the hash computation by performing final operations
  220. * such as padding. The digest is reset after this call is made.
  221. *
  222. * @return the array of bytes for the resulting hash value.
  223. */
  224. public byte[] digest() {
  225. /* Resetting is the responsibility of implementors. */
  226. byte[] result = engineDigest();
  227. state = INITIAL;
  228. return result;
  229. }
  230. /**
  231. * Completes the hash computation by performing final operations
  232. * such as padding. The digest is reset after this call is made.
  233. *
  234. * @param buf output buffer for the computed digest
  235. *
  236. * @param offset offset into the output buffer to begin storing the digest
  237. *
  238. * @param len number of bytes within buf allotted for the digest
  239. *
  240. * @return the number of bytes placed into <code>buf</code>
  241. *
  242. * @exception DigestException if an error occurs.
  243. */
  244. public int digest(byte[] buf, int offset, int len) throws DigestException {
  245. if (buf == null) {
  246. throw new IllegalArgumentException("No output buffer given");
  247. }
  248. if (buf.length - offset < len) {
  249. throw new IllegalArgumentException
  250. ("Output buffer too small for specified offset and length");
  251. }
  252. int numBytes = engineDigest(buf, offset, len);
  253. state = INITIAL;
  254. return numBytes;
  255. }
  256. /**
  257. * Performs a final update on the digest using the specified array
  258. * of bytes, then completes the digest computation. That is, this
  259. * method first calls {@link #update(byte[]) update(input)},
  260. * passing the <i>input</i> array to the <code>update</code> method,
  261. * then calls {@link #digest() digest()}.
  262. *
  263. * @param input the input to be updated before the digest is
  264. * completed.
  265. *
  266. * @return the array of bytes for the resulting hash value.
  267. */
  268. public byte[] digest(byte[] input) {
  269. update(input);
  270. return digest();
  271. }
  272. /**
  273. * Returns a string representation of this message digest object.
  274. */
  275. public String toString() {
  276. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  277. PrintStream p = new PrintStream(baos);
  278. p.print(algorithm+" Message Digest from "+provider.getName()+", ");
  279. switch (state) {
  280. case INITIAL:
  281. p.print("<initialized>");
  282. break;
  283. case IN_PROGRESS:
  284. p.print("<in progress>");
  285. break;
  286. }
  287. p.println();
  288. return (baos.toString());
  289. }
  290. /**
  291. * Compares two digests for equality. Does a simple byte compare.
  292. *
  293. * @param digesta one of the digests to compare.
  294. *
  295. * @param digestb the other digest to compare.
  296. *
  297. * @return true if the digests are equal, false otherwise.
  298. */
  299. public static boolean isEqual(byte digesta[], byte digestb[]) {
  300. if (digesta.length != digestb.length)
  301. return false;
  302. for (int i = 0; i < digesta.length; i++) {
  303. if (digesta[i] != digestb[i]) {
  304. return false;
  305. }
  306. }
  307. return true;
  308. }
  309. /**
  310. * Resets the digest for further use.
  311. */
  312. public void reset() {
  313. engineReset();
  314. state = INITIAL;
  315. }
  316. /**
  317. * Returns a string that identifies the algorithm, independent of
  318. * implementation details. The name should be a standard
  319. * Java Security name (such as "SHA", "MD5", and so on).
  320. * See Appendix A in the <a href=
  321. * "../../../guide/security/CryptoSpec.html#AppA">
  322. * Java Cryptography Architecture API Specification & Reference </a>
  323. * for information about standard algorithm names.
  324. *
  325. * @return the name of the algorithm
  326. */
  327. public final String getAlgorithm() {
  328. return this.algorithm;
  329. }
  330. /**
  331. * Returns the length of the digest in bytes, or 0 if this operation is
  332. * not supported by the provider and the implementation is not cloneable.
  333. *
  334. * @return the digest length in bytes, or 0 if this operation is not
  335. * supported by the provider and the implementation is not cloneable.
  336. *
  337. * @since 1.2
  338. */
  339. public final int getDigestLength() {
  340. int digestLen = engineGetDigestLength();
  341. if (digestLen == 0) {
  342. try {
  343. MessageDigest md = (MessageDigest)clone();
  344. byte[] digest = md.digest();
  345. return digest.length;
  346. } catch (CloneNotSupportedException e) {
  347. return digestLen;
  348. }
  349. }
  350. return digestLen;
  351. }
  352. /**
  353. * Returns a clone if the implementation is cloneable.
  354. *
  355. * @return a clone if the implementation is cloneable.
  356. *
  357. * @exception CloneNotSupportedException if this is called on an
  358. * implementation that does not support <code>Cloneable</code>.
  359. */
  360. public Object clone() throws CloneNotSupportedException {
  361. if (this instanceof Cloneable) {
  362. return super.clone();
  363. } else {
  364. throw new CloneNotSupportedException();
  365. }
  366. }
  367. /*
  368. * The following class allows providers to extend from MessageDigestSpi
  369. * rather than from MessageDigest. It represents a MessageDigest with an
  370. * encapsulated, provider-supplied SPI object (of type MessageDigestSpi).
  371. * If the provider implementation is an instance of MessageDigestSpi,
  372. * the getInstance() methods above return an instance of this class, with
  373. * the SPI object encapsulated.
  374. *
  375. * Note: All SPI methods from the original MessageDigest class have been
  376. * moved up the hierarchy into a new class (MessageDigestSpi), which has
  377. * been interposed in the hierarchy between the API (MessageDigest)
  378. * and its original parent (Object).
  379. */
  380. static class Delegate extends MessageDigest {
  381. // The provider implementation (delegate)
  382. private MessageDigestSpi digestSpi;
  383. // constructor
  384. public Delegate(MessageDigestSpi digestSpi, String algorithm) {
  385. super(algorithm);
  386. this.digestSpi = digestSpi;
  387. }
  388. /*
  389. * Returns a clone if the delegate is cloneable.
  390. *
  391. * @return a clone if the delegate is cloneable.
  392. *
  393. * @exception CloneNotSupportedException if this is called on a
  394. * delegate that does not support <code>Cloneable</code>.
  395. */
  396. public Object clone() throws CloneNotSupportedException {
  397. if (digestSpi instanceof Cloneable) {
  398. MessageDigestSpi digestSpiClone =
  399. (MessageDigestSpi)digestSpi.clone();
  400. // Because 'algorithm', 'provider', and 'state' are private
  401. // members of our supertype, we must perform a cast to
  402. // access them.
  403. MessageDigest that =
  404. new Delegate(digestSpiClone,
  405. ((MessageDigest)this).algorithm);
  406. that.provider = ((MessageDigest)this).provider;
  407. that.state = ((MessageDigest)this).state;
  408. return that;
  409. } else {
  410. throw new CloneNotSupportedException();
  411. }
  412. }
  413. protected int engineGetDigestLength() {
  414. return digestSpi.engineGetDigestLength();
  415. }
  416. protected void engineUpdate(byte input) {
  417. digestSpi.engineUpdate(input);
  418. }
  419. protected void engineUpdate(byte[] input, int offset, int len) {
  420. digestSpi.engineUpdate(input, offset, len);
  421. }
  422. protected byte[] engineDigest() {
  423. return digestSpi.engineDigest();
  424. }
  425. protected int engineDigest(byte[] buf, int offset, int len)
  426. throws DigestException {
  427. return digestSpi.engineDigest(buf, offset, len);
  428. }
  429. protected void engineReset() {
  430. digestSpi.engineReset();
  431. }
  432. }
  433. }