Dead
[official-gcc.git] / gomp-20050608-branch / libjava / classpath / java / security / MessageDigest.java
blob8a6af645be1ea3c15c13edf91fbf120388f57c41
1 /* MessageDigest.java --- The message digest interface.
2 Copyright (C) 1999, 2002, 2003, 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package java.security;
40 import gnu.java.security.Engine;
42 /**
43 * <p>This <code>MessageDigest</code> class provides applications the
44 * functionality of a message digest algorithm, such as <i>MD5</i> or <i>SHA</i>.
45 * Message digests are secure one-way hash functions that take arbitrary-sized
46 * data and output a fixed-length hash value.</p>
48 * <p>A <code>MessageDigest</code> object starts out initialized. The data is
49 * processed through it using the <code>update()</code> methods. At any point
50 * <code>reset()</code> can be called to reset the digest. Once all the data to
51 * be updated has been updated, one of the <code>digest()</code> methods should
52 * be called to complete the hash computation.</p>
54 * <p>The <code>digest()</code> method can be called <b>once</b> for a given
55 * number of updates. After <code>digest()</code> has been called, the
56 * <code>MessageDigest</code> object is <b>reset</b> to its initialized state.
57 * </p>
59 * <p>Implementations are free to implement the {@link Cloneable} interface.
60 * Client applications can test cloneability by attempting cloning and catching
61 * the {@link CloneNotSupportedException}:
63 * <pre>
64 * MessageDigest md = MessageDigest.getInstance("SHA");
65 * try
66 * {
67 * md.update(toChapter1);
68 * MessageDigest tc1 = md.clone();
69 * byte[] toChapter1Digest = tc1.digest();
70 * md.update(toChapter2);
71 * // ...
72 * }
73 * catch (CloneNotSupportedException x)
74 * {
75 * throw new DigestException("couldn't make digest of partial content");
76 * }
77 * </pre>
79 * <p>Note that if a given implementation is not cloneable, it is still possible
80 * to compute intermediate digests by instantiating several instances, if the
81 * number of digests is known in advance.</p>
83 * <p>Note that this class is abstract and extends from {@link MessageDigestSpi}
84 * for historical reasons. Application developers should only take notice of the
85 * methods defined in this <code>MessageDigest</code> class; all the methods in
86 * the superclass are intended for cryptographic service providers who wish to
87 * supply their own implementations of message digest algorithms.</p>
89 * @see MessageDigestSpi
90 * @see Provider
91 * @since JDK 1.1
93 public abstract class MessageDigest extends MessageDigestSpi
95 /** The service name for message digests. */
96 private static final String MESSAGE_DIGEST = "MessageDigest";
98 private String algorithm;
99 Provider provider;
100 private byte[] lastDigest;
103 * Creates a message digest with the specified algorithm name.
105 * @param algorithm the standard name of the digest algorithm.
106 * See Appendix A in the Java Cryptography Architecture API
107 * Specification &amp; Reference for information about standard
108 * algorithm names.
110 protected MessageDigest(String algorithm)
112 this.algorithm = algorithm;
113 provider = null;
117 * Generates a <code>MessageDigest</code> object that implements the specified
118 * digest algorithm. If the default provider package provides an
119 * implementation of the requested digest algorithm, an instance of
120 * <code>MessageDigest</code> containing that implementation is returned. If
121 * the algorithm is not available in the default package, other packages are
122 * searched.
124 * @param algorithm the name of the algorithm requested. See Appendix A in the
125 * Java Cryptography Architecture API Specification &amp; Reference for
126 * information about standard algorithm names.
127 * @return a Message Digest object implementing the specified algorithm.
128 * @throws NoSuchAlgorithmException if the algorithm is not available in the
129 * caller's environment.
131 public static MessageDigest getInstance(String algorithm)
132 throws NoSuchAlgorithmException
134 Provider[] p = Security.getProviders();
135 for (int i = 0; i < p.length; i++)
139 return getInstance(algorithm, p[i]);
141 catch (NoSuchAlgorithmException ignored)
143 // Ignore.
147 throw new NoSuchAlgorithmException(algorithm);
151 * Generates a <code>MessageDigest</code> object implementing the specified
152 * algorithm, as supplied from the specified provider, if such an algorithm is
153 * available from the provider.
155 * @param algorithm the name of the algorithm requested. See Appendix A in the
156 * Java Cryptography Architecture API Specification &amp; Reference for
157 * information about standard algorithm names.
158 * @param provider the name of the provider.
159 * @return a Message Digest object implementing the specified algorithm.
160 * @throws NoSuchAlgorithmException if the algorithm is not available in the
161 * package supplied by the requested provider.
162 * @throws NoSuchProviderException if the provider is not available in the
163 * environment.
164 * @throws IllegalArgumentException if the provider name is null or empty.
165 * @see Provider
167 public static MessageDigest getInstance(String algorithm, String provider)
168 throws NoSuchAlgorithmException, NoSuchProviderException
170 if (provider != null)
171 provider = provider.trim();
173 if (provider == null || provider.length() == 0)
174 throw new IllegalArgumentException("Illegal provider");
176 Provider p = Security.getProvider(provider);
177 if (p == null)
178 throw new NoSuchProviderException(provider);
180 return getInstance(algorithm, p);
184 * Generates a <code>MessageDigest</code> object implementing the specified
185 * algorithm, as supplied from the specified provider, if such an algorithm
186 * is available from the provider. Note: the provider doesn't have to be
187 * registered.
189 * @param algorithm the name of the algorithm requested. See Appendix A in
190 * the Java Cryptography Architecture API Specification &amp; Reference for
191 * information about standard algorithm names.
192 * @param provider the provider.
193 * @return a Message Digest object implementing the specified algorithm.
194 * @throws NoSuchAlgorithmException if the <code>algorithm</code> is not
195 * available in the package supplied by the requested <code>provider</code>.
196 * @throws IllegalArgumentException if the <code>provider</code> is
197 * <code>null</code>.
198 * @since 1.4
199 * @see Provider
201 public static MessageDigest getInstance(String algorithm, Provider provider)
202 throws NoSuchAlgorithmException
204 if (provider == null)
205 throw new IllegalArgumentException("Illegal provider");
207 MessageDigest result = null;
208 Object o = null;
211 o = Engine.getInstance(MESSAGE_DIGEST, algorithm, provider);
213 catch (java.lang.reflect.InvocationTargetException ite)
215 throw new NoSuchAlgorithmException(algorithm);
218 if (o instanceof MessageDigestSpi)
220 result = new DummyMessageDigest((MessageDigestSpi) o, algorithm);
222 else if (o instanceof MessageDigest)
224 result = (MessageDigest) o;
225 result.algorithm = algorithm;
227 else
229 throw new NoSuchAlgorithmException(algorithm);
231 result.provider = provider;
232 return result;
236 * Returns the provider of this message digest object.
238 * @return the provider of this message digest object.
240 public final Provider getProvider()
242 return provider;
246 * Updates the digest using the specified byte.
248 * @param input the byte with which to update the digest.
250 public void update(byte input)
252 engineUpdate(input);
256 * Updates the digest using the specified array of bytes, starting at the
257 * specified offset.
259 * @param input the array of bytes.
260 * @param offset the offset to start from in the array of bytes.
261 * @param len the number of bytes to use, starting at offset.
263 public void update(byte[] input, int offset, int len)
265 engineUpdate(input, offset, len);
269 * Updates the digest using the specified array of bytes.
271 * @param input the array of bytes.
273 public void update(byte[] input)
275 engineUpdate(input, 0, input.length);
279 * Completes the hash computation by performing final operations such as
280 * padding. The digest is reset after this call is made.
282 * @return the array of bytes for the resulting hash value.
284 public byte[] digest()
286 return lastDigest = engineDigest();
290 * Completes the hash computation by performing final operations such as
291 * padding. The digest is reset after this call is made.
293 * @param buf An output buffer for the computed digest.
294 * @param offset The offset into the output buffer to begin storing the digest.
295 * @param len The number of bytes within buf allotted for the digest.
296 * @return The number of bytes placed into buf.
297 * @throws DigestException if an error occurs.
299 public int digest(byte[] buf, int offset, int len) throws DigestException
301 return engineDigest(buf, offset, len);
305 * Performs a final update on the digest using the specified array of bytes,
306 * then completes the digest computation. That is, this method first calls
307 * <code>update(input)</code>, passing the input array to the <code>update()
308 * </code> method, then calls <code>digest()</code>.
310 * @param input the input to be updated before the digest is completed.
311 * @return the array of bytes for the resulting hash value.
313 public byte[] digest(byte[] input)
315 update(input);
316 return digest();
320 * Returns a string representation of this message digest object.
322 * @return a string representation of the object.
324 public String toString()
326 return (getClass()).getName() + " Message Digest <" + digestToString() + ">";
330 * Compares two digests for equality. Does a simple byte compare.
332 * @param digesta one of the digests to compare.
333 * @param digestb the other digest to compare.
334 * @return <code>true</code> if the digests are equal, <code>false</code>
335 * otherwise.
337 public static boolean isEqual(byte[] digesta, byte[] digestb)
339 if (digesta.length != digestb.length)
340 return false;
342 for (int i = digesta.length - 1; i >= 0; --i)
343 if (digesta[i] != digestb[i])
344 return false;
346 return true;
349 /** Resets the digest for further use. */
350 public void reset()
352 engineReset();
356 * Returns a string that identifies the algorithm, independent of
357 * implementation details. The name should be a standard Java Security name
358 * (such as <code>"SHA"</code>, <code>"MD5"</code>, and so on). See Appendix
359 * A in the Java Cryptography Architecture API Specification &amp; Reference
360 * for information about standard algorithm names.
362 * @return the name of the algorithm.
364 public final String getAlgorithm()
366 return algorithm;
370 * Returns the length of the digest in bytes, or <code>0</code> if this
371 * operation is not supported by the provider and the implementation is not
372 * cloneable.
374 * @return the digest length in bytes, or <code>0</code> if this operation is
375 * not supported by the provider and the implementation is not cloneable.
376 * @since 1.2
378 public final int getDigestLength()
380 return engineGetDigestLength();
384 * Returns a clone if the implementation is cloneable.
386 * @return a clone if the implementation is cloneable.
387 * @throws CloneNotSupportedException if this is called on an implementation
388 * that does not support {@link Cloneable}.
390 public Object clone() throws CloneNotSupportedException
392 return super.clone();
395 private String digestToString()
397 byte[] digest = lastDigest;
399 if (digest == null)
400 return "incomplete";
402 StringBuffer buf = new StringBuffer();
403 int len = digest.length;
404 for (int i = 0; i < len; ++i)
406 byte b = digest[i];
407 byte high = (byte) ((b & 0xff) >>> 4);
408 byte low = (byte) (b & 0xf);
410 buf.append(high > 9 ? ('a' - 10) + high : '0' + high);
411 buf.append(low > 9 ? ('a' - 10) + low : '0' + low);
414 return buf.toString();