KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > security > MessageDigestSpi


1 /*
2  * @(#)MessageDigestSpi.java 1.15 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.security;
9
10 import java.util.*;
11 import java.lang.*;
12 import java.io.IOException JavaDoc;
13 import java.io.ByteArrayOutputStream JavaDoc;
14 import java.io.PrintStream JavaDoc;
15 import java.io.InputStream JavaDoc;
16 import java.io.ByteArrayInputStream JavaDoc;
17
18 import java.nio.ByteBuffer JavaDoc;
19
20 import sun.security.jca.JCAUtil;
21
22 /**
23  * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
24  * for the <code>MessageDigest</code> class, which provides the functionality
25  * of a message digest algorithm, such as MD5 or SHA. Message digests are
26  * secure one-way hash functions that take arbitrary-sized data and output a
27  * fixed-length hash value.
28  *
29  * <p> All the abstract methods in this class must be implemented by a
30  * cryptographic service provider who wishes to supply the implementation
31  * of a particular message digest algorithm.
32  *
33  * <p> Implementations are free to implement the Cloneable interface.
34  *
35  * @author Benjamin Renaud
36  *
37  * @version 1.15, 12/19/03
38  *
39  * @see MessageDigest
40  */

41
42 public abstract class MessageDigestSpi {
43
44     /**
45      * Returns the digest length in bytes.
46      *
47      * <p>This concrete method has been added to this previously-defined
48      * abstract class. (For backwards compatibility, it cannot be abstract.)
49      *
50      * <p>The default behavior is to return 0.
51      *
52      * <p>This method may be overridden by a provider to return the digest
53      * length.
54      *
55      * @return the digest length in bytes.
56      *
57      * @since 1.2
58      */

59     protected int engineGetDigestLength() {
60     return 0;
61     }
62
63     /**
64      * Updates the digest using the specified byte.
65      *
66      * @param input the byte to use for the update.
67      */

68     protected abstract void engineUpdate(byte input);
69
70     /**
71      * Updates the digest using the specified array of bytes,
72      * starting at the specified offset.
73      *
74      * @param input the array of bytes to use for the update.
75      *
76      * @param offset the offset to start from in the array of bytes.
77      *
78      * @param len the number of bytes to use, starting at
79      * <code>offset</code>.
80      */

81     protected abstract void engineUpdate(byte[] input, int offset, int len);
82
83     /**
84      * Update the digest using the specified ByteBuffer. The digest is
85      * updated using the <code>input.remaining()</code> bytes starting
86      * at <code>input.position()</code>.
87      * Upon return, the buffer's position will be equal to its limit;
88      * its limit will not have changed.
89      *
90      * @param input the ByteBuffer
91      * @since 1.5
92      */

93     protected void engineUpdate(ByteBuffer JavaDoc input) {
94     if (input.hasRemaining() == false) {
95         return;
96     }
97     if (input.hasArray()) {
98         byte[] b = input.array();
99         int ofs = input.arrayOffset();
100         int pos = input.position();
101         int lim = input.limit();
102         engineUpdate(b, ofs + pos, lim - pos);
103         input.position(lim);
104     } else {
105         int len = input.remaining();
106         byte[] b = new byte[JCAUtil.getTempArraySize(len)];
107         while (len > 0) {
108         int chunk = Math.min(len, b.length);
109         input.get(b, 0, chunk);
110         engineUpdate(b, 0, chunk);
111         len -= chunk;
112         }
113     }
114     }
115
116     /**
117      * Completes the hash computation by performing final
118      * operations such as padding. Once <code>engineDigest</code> has
119      * been called, the engine should be reset (see
120      * {@link #engineReset() engineReset}).
121      * Resetting is the responsibility of the
122      * engine implementor.
123      *
124      * @return the array of bytes for the resulting hash value.
125      */

126     protected abstract byte[] engineDigest();
127
128     /**
129      * Completes the hash computation by performing final
130      * operations such as padding. Once <code>engineDigest</code> has
131      * been called, the engine should be reset (see
132      * {@link #engineReset() engineReset}).
133      * Resetting is the responsibility of the
134      * engine implementor.
135      *
136      * This method should be abstract, but we leave it concrete for
137      * binary compatibility. Knowledgeable providers should override this
138      * method.
139      *
140      * @param buf the output buffer in which to store the digest
141      *
142      * @param offset offset to start from in the output buffer
143      *
144      * @param len number of bytes within buf allotted for the digest.
145      * Both this default implementation and the SUN provider do not
146      * return partial digests. The presence of this parameter is solely
147      * for consistency in our API's. If the value of this parameter is less
148      * than the actual digest length, the method will throw a DigestException.
149      * This parameter is ignored if its value is greater than or equal to
150      * the actual digest length.
151      *
152      * @return the length of the digest stored in the output buffer.
153      *
154      * @exception DigestException if an error occurs.
155      *
156      * @since 1.2
157      */

158     protected int engineDigest(byte[] buf, int offset, int len)
159                         throws DigestException JavaDoc {
160
161     byte[] digest = engineDigest();
162     if (len < digest.length)
163         throw new DigestException JavaDoc("partial digests not returned");
164     if (buf.length - offset < digest.length)
165         throw new DigestException JavaDoc("insufficient space in the output "
166                       + "buffer to store the digest");
167     System.arraycopy(digest, 0, buf, offset, digest.length);
168     return digest.length;
169     }
170
171     /**
172      * Resets the digest for further use.
173      */

174     protected abstract void engineReset();
175
176     /**
177      * Returns a clone if the implementation is cloneable.
178      *
179      * @return a clone if the implementation is cloneable.
180      *
181      * @exception CloneNotSupportedException if this is called on an
182      * implementation that does not support <code>Cloneable</code>.
183      */

184     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
185     if (this instanceof Cloneable JavaDoc) {
186         return super.clone();
187     } else {
188         throw new CloneNotSupportedException JavaDoc();
189     }
190     }
191 }
192
Popular Tags