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