1. /*
  2. * @(#)MessageDigestSpi.java 1.11 00/02/02
  3. *
  4. * Copyright 1997-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 class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
  20. * for the <code>MessageDigest</code> class, which provides the functionality
  21. * of a message digest algorithm, such as MD5 or SHA. Message digests are
  22. * secure one-way hash functions that take arbitrary-sized data and output a
  23. * fixed-length hash value.
  24. *
  25. * <p> All the abstract methods in this class must be implemented by a
  26. * cryptographic service provider who wishes to supply the implementation
  27. * of a particular message digest algorithm.
  28. *
  29. * <p> Implementations are free to implement the Cloneable interface.
  30. *
  31. * @author Benjamin Renaud
  32. *
  33. * @version 1.11, 02/02/00
  34. *
  35. * @see MessageDigest
  36. */
  37. public abstract class MessageDigestSpi {
  38. /**
  39. * Returns the digest length in bytes.
  40. *
  41. * <p>This concrete method has been added to this previously-defined
  42. * abstract class. (For backwards compatibility, it cannot be abstract.)
  43. *
  44. * <p>The default behavior is to return 0.
  45. *
  46. * <p>This method may be overridden by a provider to return the digest
  47. * length.
  48. *
  49. * @return the digest length in bytes.
  50. *
  51. * @since 1.2
  52. */
  53. protected int engineGetDigestLength() {
  54. return 0;
  55. }
  56. /**
  57. * Updates the digest using the specified byte.
  58. *
  59. * @param input the byte to use for the update.
  60. */
  61. protected abstract void engineUpdate(byte input);
  62. /**
  63. * Updates the digest using the specified array of bytes,
  64. * starting at the specified offset.
  65. *
  66. * @param input the array of bytes to use for the update.
  67. *
  68. * @param offset the offset to start from in the array of bytes.
  69. *
  70. * @param len the number of bytes to use, starting at
  71. * <code>offset</code>.
  72. */
  73. protected abstract void engineUpdate(byte[] input, int offset, int len);
  74. /**
  75. * Completes the hash computation by performing final
  76. * operations such as padding. Once <code>engineDigest</code> has
  77. * been called, the engine should be reset (see
  78. * {@link #engineReset() engineReset}).
  79. * Resetting is the responsibility of the
  80. * engine implementor.
  81. *
  82. * @return the array of bytes for the resulting hash value.
  83. */
  84. protected abstract byte[] engineDigest();
  85. /**
  86. * Completes the hash computation by performing final
  87. * operations such as padding. Once <code>engineDigest</code> has
  88. * been called, the engine should be reset (see
  89. * {@link #engineReset() engineReset}).
  90. * Resetting is the responsibility of the
  91. * engine implementor.
  92. *
  93. * This method should be abstract, but we leave it concrete for
  94. * binary compatibility. Knowledgeable providers should override this
  95. * method.
  96. *
  97. * @param buf the output buffer in which to store the digest
  98. *
  99. * @param offset offset to start from in the output buffer
  100. *
  101. * @param len number of bytes within buf allotted for the digest.
  102. * Both this default implementation and the SUN provider do not
  103. * return partial digests. The presence of this parameter is solely
  104. * for consistency in our API's. If the value of this parameter is less
  105. * than the actual digest length, the method will throw a DigestException.
  106. * This parameter is ignored if its value is greater than or equal to
  107. * the actual digest length.
  108. *
  109. * @return the length of the digest stored in the output buffer.
  110. *
  111. * @exception DigestException if an error occurs.
  112. *
  113. * @since 1.2
  114. */
  115. protected int engineDigest(byte[] buf, int offset, int len)
  116. throws DigestException {
  117. byte[] digest = engineDigest();
  118. if (len < digest.length)
  119. throw new DigestException("partial digests not returned");
  120. if (buf.length - offset < digest.length)
  121. throw new DigestException("insufficient space in the output "
  122. + "buffer to store the digest");
  123. System.arraycopy(digest, 0, buf, offset, digest.length);
  124. return digest.length;
  125. }
  126. /**
  127. * Resets the digest for further use.
  128. */
  129. protected abstract void engineReset();
  130. /**
  131. * Returns a clone if the implementation is cloneable.
  132. *
  133. * @return a clone if the implementation is cloneable.
  134. *
  135. * @exception CloneNotSupportedException if this is called on an
  136. * implementation that does not support <code>Cloneable</code>.
  137. */
  138. public Object clone() throws CloneNotSupportedException {
  139. if (this instanceof Cloneable) {
  140. return super.clone();
  141. } else {
  142. throw new CloneNotSupportedException();
  143. }
  144. }
  145. }