001: /*
002: * @(#)MessageDigestSpi.java 1.17 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package java.security;
029:
030: import java.util.*;
031: import java.lang.*;
032: import java.io.IOException;
033: import java.io.ByteArrayOutputStream;
034: import java.io.PrintStream;
035: import java.io.InputStream;
036: import java.io.ByteArrayInputStream;
037:
038: /**
039: * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
040: * for the <code>MessageDigest</code> class, which provides the functionality
041: * of a message digest algorithm, such as MD5 or SHA. Message digests are
042: * secure one-way hash functions that take arbitrary-sized data and output a
043: * fixed-length hash value.
044: *
045: * <p> All the abstract methods in this class must be implemented by a
046: * cryptographic service provider who wishes to supply the implementation
047: * of a particular message digest algorithm.
048: *
049: * <p> Implementations are free to implement the Cloneable interface.
050: *
051: * @author Benjamin Renaud
052: *
053: * @version 1.11, 02/02/00
054: *
055: * @see MessageDigest
056: */
057:
058: public abstract class MessageDigestSpi {
059:
060: /**
061: * Returns the digest length in bytes.
062: *
063: * <p>This concrete method has been added to this previously-defined
064: * abstract class. (For backwards compatibility, it cannot be abstract.)
065: *
066: * <p>The default behavior is to return 0.
067: *
068: * <p>This method may be overridden by a provider to return the digest
069: * length.
070: *
071: * @return the digest length in bytes.
072: *
073: * @since 1.2
074: */
075: protected int engineGetDigestLength() {
076: return 0;
077: }
078:
079: /**
080: * Updates the digest using the specified byte.
081: *
082: * @param input the byte to use for the update.
083: */
084: protected abstract void engineUpdate(byte input);
085:
086: /**
087: * Updates the digest using the specified array of bytes,
088: * starting at the specified offset.
089: *
090: * @param input the array of bytes to use for the update.
091: *
092: * @param offset the offset to start from in the array of bytes.
093: *
094: * @param len the number of bytes to use, starting at
095: * <code>offset</code>.
096: */
097: protected abstract void engineUpdate(byte[] input, int offset,
098: int len);
099:
100: /**
101: * Completes the hash computation by performing final
102: * operations such as padding. Once <code>engineDigest</code> has
103: * been called, the engine should be reset (see
104: * {@link #engineReset() engineReset}).
105: * Resetting is the responsibility of the
106: * engine implementor.
107: *
108: * @return the array of bytes for the resulting hash value.
109: */
110: protected abstract byte[] engineDigest();
111:
112: /**
113: * Completes the hash computation by performing final
114: * operations such as padding. Once <code>engineDigest</code> has
115: * been called, the engine should be reset (see
116: * {@link #engineReset() engineReset}).
117: * Resetting is the responsibility of the
118: * engine implementor.
119: *
120: * This method should be abstract, but we leave it concrete for
121: * binary compatibility. Knowledgeable providers should override this
122: * method.
123: *
124: * @param buf the output buffer in which to store the digest
125: *
126: * @param offset offset to start from in the output buffer
127: *
128: * @param len number of bytes within buf allotted for the digest.
129: * Both this default implementation and the SUN provider do not
130: * return partial digests. The presence of this parameter is solely
131: * for consistency in our API's. If the value of this parameter is less
132: * than the actual digest length, the method will throw a DigestException.
133: * This parameter is ignored if its value is greater than or equal to
134: * the actual digest length.
135: *
136: * @return the length of the digest stored in the output buffer.
137: *
138: * @exception DigestException if an error occurs.
139: *
140: * @since 1.2
141: */
142: protected int engineDigest(byte[] buf, int offset, int len)
143: throws DigestException {
144:
145: byte[] digest = engineDigest();
146: if (len < digest.length)
147: throw new DigestException("partial digests not returned");
148: if (buf.length - offset < digest.length)
149: throw new DigestException(
150: "insufficient space in the output "
151: + "buffer to store the digest");
152: System.arraycopy(digest, 0, buf, offset, digest.length);
153: return digest.length;
154: }
155:
156: /**
157: * Resets the digest for further use.
158: */
159: protected abstract void engineReset();
160:
161: /**
162: * Returns a clone if the implementation is cloneable.
163: *
164: * @return a clone if the implementation is cloneable.
165: *
166: * @exception CloneNotSupportedException if this is called on an
167: * implementation that does not support <code>Cloneable</code>.
168: */
169: public Object clone() throws CloneNotSupportedException {
170: if (this instanceof Cloneable) {
171: return super .clone();
172: } else {
173: throw new CloneNotSupportedException();
174: }
175: }
176: }
|