aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/security/MessageDigest.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/security/MessageDigest.java')
-rw-r--r--libjava/java/security/MessageDigest.java352
1 files changed, 196 insertions, 156 deletions
diff --git a/libjava/java/security/MessageDigest.java b/libjava/java/security/MessageDigest.java
index 10032f2..cbf0e07 100644
--- a/libjava/java/security/MessageDigest.java
+++ b/libjava/java/security/MessageDigest.java
@@ -1,6 +1,5 @@
-
/* MessageDigest.java --- The message digest interface.
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,17 +37,73 @@ exception statement from your version. */
package java.security;
+/**
+ * <p>This <code>MessageDigest</code> class provides applications the
+ * functionality of a message digest algorithm, such as <i>MD5</i> or <i>SHA</i>.
+ * Message digests are secure one-way hash functions that take arbitrary-sized
+ * data and output a fixed-length hash value.</p>
+ *
+ * <p>A <code>MessageDigest</code> object starts out initialized. The data is
+ * processed through it using the <code>update()</code> methods. At any point
+ * <code>reset()</code> can be called to reset the digest. Once all the data to
+ * be updated has been updated, one of the <code>digest()</code> methods should
+ * be called to complete the hash computation.</p>
+ *
+ * <p>The <code>digest()</code> method can be called <b>once</b> for a given
+ * number of updates. After <code>digest()</code> has been called, the
+ * <code>MessageDigest</code> object is <b>reset</b> to its initialized state.
+ * </p>
+ *
+ * <p>Implementations are free to implement the {@link Cloneable} interface.
+ * Client applications can test cloneability by attempting cloning and catching
+ * the {@link CloneNotSupportedException}:
+ *
+ * <pre>
+ * MessageDigest md = MessageDigest.getInstance("SHA");
+ * try
+ * {
+ * md.update(toChapter1);
+ * MessageDigest tc1 = md.clone();
+ * byte[] toChapter1Digest = tc1.digest();
+ * md.update(toChapter2);
+ * // ...
+ * }
+ * catch (CloneNotSupportedException x)
+ * {
+ * throw new DigestException("couldn't make digest of partial content");
+ * }
+ * </pre>
+ *
+ * <p>Note that if a given implementation is not cloneable, it is still possible
+ * to compute intermediate digests by instantiating several instances, if the
+ * number of digests is known in advance.</p>
+ *
+ * <p>Note that this class is abstract and extends from {@link MessageDigestSpi}
+ * for historical reasons. Application developers should only take notice of the
+ * methods defined in this <code>MessageDigest</code> class; all the methods in
+ * the superclass are intended for cryptographic service providers who wish to
+ * supply their own implementations of message digest algorithms.</p>
+ *
+ * @see MessageDigestSpi
+ * @see Provider
+ * @since JDK 1.1
+ */
public abstract class MessageDigest extends MessageDigestSpi
{
+ /** The service name for message digests. */
+ private static final String MESSAGE_DIGEST = "MessageDigest";
+
private String algorithm;
Provider provider;
private byte[] lastDigest;
/**
- Creates a MessageDigest representing the specified
- algorithm.
-
- @param algorithm the name of digest algorithm to choose
+ * Creates a message digest with the specified algorithm name.
+ *
+ * @param algorithm the standard name of the digest algorithm.
+ * See Appendix A in the Java Cryptography Architecture API
+ * Specification &amp; Reference for information about standard
+ * algorithm names.
*/
protected MessageDigest(String algorithm)
{
@@ -56,16 +111,20 @@ public abstract class MessageDigest extends MessageDigestSpi
provider = null;
}
- /**
- Gets an instance of the MessageDigest class representing
- the specified digest. If the algorithm is not found then,
- it throws NoSuchAlgorithmException.
-
- @param algorithm the name of digest algorithm to choose
- @return a MessageDigest representing the desired algorithm
-
- @exception NoSuchAlgorithmException if the algorithm is not implemented by
- providers
+ /**
+ * Generates a <code>MessageDigest</code> object that implements the specified
+ * digest algorithm. If the default provider package provides an
+ * implementation of the requested digest algorithm, an instance of
+ * <code>MessageDigest</code> containing that implementation is returned. If
+ * the algorithm is not available in the default package, other packages are
+ * searched.
+ *
+ * @param algorithm the name of the algorithm requested. See Appendix A in the
+ * Java Cryptography Architecture API Specification &amp; Reference for
+ * information about standard algorithm names.
+ * @return a Message Digest object implementing the specified algorithm.
+ * @throws NoSuchAlgorithmException if the algorithm is not available in the
+ * caller's environment.
*/
public static MessageDigest getInstance(String algorithm)
throws NoSuchAlgorithmException
@@ -83,103 +142,84 @@ public abstract class MessageDigest extends MessageDigestSpi
throw new NoSuchAlgorithmException(algorithm);
}
- /**
- Gets an instance of the MessageDigest class representing
- the specified digest from the specified provider. If the
- algorithm is not found then, it throws NoSuchAlgorithmException.
- If the provider is not found, then it throws
- NoSuchProviderException.
-
- @param algorithm the name of digest algorithm to choose
- @param provider the name of the provider to find the algorithm in
- @return a MessageDigest representing the desired algorithm
-
- @exception NoSuchAlgorithmException if the algorithm is not implemented by
- the provider
- @exception NoSuchProviderException if the provider is not found
+ /**
+ * Generates a <code>MessageDigest</code> object implementing the specified
+ * algorithm, as supplied from the specified provider, if such an algorithm is
+ * available from the provider.
+ *
+ * @param algorithm the name of the algorithm requested. See Appendix A in the
+ * Java Cryptography Architecture API Specification &amp; Reference for
+ * information about standard algorithm names.
+ * @param provider the name of the provider.
+ * @return a Message Digest object implementing the specified algorithm.
+ * @throws NoSuchAlgorithmException if the algorithm is not available in the
+ * package supplied by the requested provider.
+ * @throws NoSuchProviderException if the provider is not available in the
+ * environment.
+ * @throws IllegalArgumentException if the provider name is null or empty.
+ * @see Provider
*/
-
public static MessageDigest getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException
{
- Provider p = Security.getProvider(provider);
+ if (provider == null || provider.length() == 0)
+ throw new IllegalArgumentException("Illegal provider");
+ Provider p = Security.getProvider(provider);
if (p == null)
throw new NoSuchProviderException(provider);
return getInstance(algorithm, p);
}
- private static MessageDigest getInstance(String algorithm, Provider p)
- throws NoSuchAlgorithmException
- {
- // try the name as is
- String className = p.getProperty("MessageDigest." + algorithm);
- if (className == null) { // try all uppercase
- String upper = algorithm.toUpperCase();
- className = p.getProperty("MessageDigest." + upper);
- if (className == null) { // try if it's an alias
- String alias = p.getProperty("Alg.Alias.MessageDigest." +algorithm);
- if (alias == null) { // try all-uppercase alias name
- alias = p.getProperty("Alg.Alias.MessageDigest." +upper);
- if (alias == null) { // spit the dummy
- throw new NoSuchAlgorithmException(algorithm);
- }
- }
- className = p.getProperty("MessageDigest." + alias);
- if (className == null) {
- throw new NoSuchAlgorithmException(algorithm);
- }
- }
- }
- return getInstance(className, algorithm, p);
- }
-
- private static MessageDigest getInstance(String classname,
- String algorithm,
- Provider provider)
+ /**
+ * Generates a <code>MessageDigest</code> object implementing the specified
+ * algorithm, as supplied from the specified provider, if such an algorithm
+ * is available from the provider. Note: the provider doesn't have to be
+ * registered.
+ *
+ * @param algorithm the name of the algorithm requested. See Appendix A in
+ * the Java Cryptography Architecture API Specification &amp; Reference for
+ * information about standard algorithm names.
+ * @param provider the provider.
+ * @return a Message Digest object implementing the specified algorithm.
+ * @throws NoSuchAlgorithmException if the <code>algorithm</code> is not
+ * available in the package supplied by the requested <code>provider</code>.
+ * @throws IllegalArgumentException if the <code>provider</code> is
+ * <code>null</code>.
+ * @since 1.4
+ * @see Provider
+ */
+ public static MessageDigest getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException
{
- if (classname == null)
- throw new NoSuchAlgorithmException(algorithm);
+ if (provider == null)
+ throw new IllegalArgumentException("Illegal provider");
MessageDigest result = null;
- try
- {
- Object obj = Class.forName(classname).newInstance();
- if (obj instanceof MessageDigest) {
- result = (MessageDigest) obj;
- result.algorithm = algorithm;
- } else if (obj instanceof MessageDigestSpi) {
- result = new DummyMessageDigest((MessageDigestSpi) obj, algorithm);
- } else {
- throw new ClassCastException("Class "+classname+" from Provider "
- +provider.getName()
- +" does not extend java.security.MessageDigestSpi");
- }
- result.provider = provider;
- return result;
- }
- catch (ClassNotFoundException cnfe)
+ Object o = Engine.getInstance(MESSAGE_DIGEST, algorithm, provider);
+
+ if (o instanceof MessageDigestSpi)
{
- throw new NoSuchAlgorithmException(algorithm + ": Class not found.");
+ result = new DummyMessageDigest((MessageDigestSpi) o, algorithm);
}
- catch (InstantiationException ie)
+ else if (o instanceof MessageDigest)
{
- throw new NoSuchAlgorithmException(algorithm
- + ": Class instantiation failed.");
+ result = (MessageDigest) o;
+ result.algorithm = algorithm;
}
- catch (IllegalAccessException iae)
+ else
{
- throw new NoSuchAlgorithmException(algorithm + ": Illegal Access");
+ throw new NoSuchAlgorithmException(algorithm);
}
+ result.provider = provider;
+ return result;
}
-
/**
- Gets the provider that the MessageDigest is from.
-
- @return the provider the this MessageDigest
+ * Returns the provider of this message digest object.
+ *
+ * @return the provider of this message digest object.
*/
public final Provider getProvider()
{
@@ -187,9 +227,9 @@ public abstract class MessageDigest extends MessageDigestSpi
}
/**
- Updates the digest with the byte.
-
- @param input byte to update the digest with
+ * Updates the digest using the specified byte.
+ *
+ * @param input the byte with which to update the digest.
*/
public void update(byte input)
{
@@ -197,32 +237,33 @@ public abstract class MessageDigest extends MessageDigestSpi
}
/**
- Updates the digest with the bytes from the array from the
- specified offset to the specified length.
-
- @param input bytes to update the digest with
- @param offset the offset to start at
- @param len length of the data to update with
+ * Updates the digest using the specified array of bytes, starting at the
+ * specified offset.
+ *
+ * @param input the array of bytes.
+ * @param offset the offset to start from in the array of bytes.
+ * @param len the number of bytes to use, starting at offset.
*/
- public void update(byte[]input, int offset, int len)
+ public void update(byte[] input, int offset, int len)
{
engineUpdate(input, offset, len);
}
/**
- Updates the digest with the bytes from the array.
-
- @param input bytes to update the digest with
+ * Updates the digest using the specified array of bytes.
+ *
+ * @param input the array of bytes.
*/
- public void update(byte[]input)
+ public void update(byte[] input)
{
engineUpdate(input, 0, input.length);
}
/**
- Computes the digest of the stored data.
-
- @return a byte array representing the message digest
+ * Completes the hash computation by performing final operations such as
+ * padding. The digest is reset after this call is made.
+ *
+ * @return the array of bytes for the resulting hash value.
*/
public byte[] digest()
{
@@ -230,52 +271,54 @@ public abstract class MessageDigest extends MessageDigestSpi
}
/**
- Computes the final digest of the stored bytes and returns
- them.
-
- @param buf An array of bytes to store the digest
- @param offset An offset to start storing the digest at
- @param len The length of the buffer
- @return Returns the length of the buffer
+ * Completes the hash computation by performing final operations such as
+ * padding. The digest is reset after this call is made.
+ *
+ * @param buf An output buffer for the computed digest.
+ * @param offset The offset into the output buffer to begin storing the digest.
+ * @param len The number of bytes within buf allotted for the digest.
+ * @return The number of bytes placed into buf.
+ * @throws DigestException if an error occurs.
*/
- public int digest(byte[]buf, int offset, int len) throws DigestException
+ public int digest(byte[] buf, int offset, int len) throws DigestException
{
return engineDigest(buf, offset, len);
}
/**
- Computes a final update using the input array of bytes,
- then computes a final digest and returns it. It calls
- update(input) and then digest();
-
- @param input An array of bytes to perform final update with
- @return a byte array representing the message digest
+ * Performs a final update on the digest using the specified array of bytes,
+ * then completes the digest computation. That is, this method first calls
+ * <code>update(input)</code>, passing the input array to the <code>update()
+ * </code> method, then calls <code>digest()</code>.
+ *
+ * @param input the input to be updated before the digest is completed.
+ * @return the array of bytes for the resulting hash value.
*/
- public byte[] digest(byte[]input)
+ public byte[] digest(byte[] input)
{
update(input);
return digest();
}
/**
- Returns a representation of the MessageDigest as a String.
-
- @return a string representing the message digest
+ * Returns a string representation of this message digest object.
+ *
+ * @return a string representation of the object.
*/
public String toString()
{
- return (getClass()).getName()
- + " Message Digest <" + digestToString() + ">";
+ return (getClass()).getName() + " Message Digest <" + digestToString() + ">";
}
/**
- Does a simple byte comparison of the two digests.
-
- @param digesta first digest to compare
- @param digestb second digest to compare
- @return true if they are equal, false otherwise
+ * Compares two digests for equality. Does a simple byte compare.
+ *
+ * @param digesta one of the digests to compare.
+ * @param digestb the other digest to compare.
+ * @return <code>true</code> if the digests are equal, <code>false</code>
+ * otherwise.
*/
- public static boolean isEqual(byte[]digesta, byte[]digestb)
+ public static boolean isEqual(byte[] digesta, byte[] digestb)
{
if (digesta.length != digestb.length)
return false;
@@ -287,20 +330,20 @@ public abstract class MessageDigest extends MessageDigestSpi
return true;
}
-
- /**
- Resets the message digest.
- */
+ /** Resets the digest for further use. */
public void reset()
{
engineReset();
}
- /**
- Gets the name of the algorithm currently used.
- The names of algorithms are usually SHA-1 or MD5.
-
- @return name of algorithm.
+ /**
+ * Returns a string that identifies the algorithm, independent of
+ * implementation details. The name should be a standard Java Security name
+ * (such as <code>"SHA"</code>, <code>"MD5"</code>, and so on). See Appendix
+ * A in the Java Cryptography Architecture API Specification &amp; Reference
+ * for information about standard algorithm names.
+ *
+ * @return the name of the algorithm.
*/
public final String getAlgorithm()
{
@@ -308,11 +351,13 @@ public abstract class MessageDigest extends MessageDigestSpi
}
/**
- Gets the length of the message digest.
- The default is zero which means that this message digest
- does not implement this function.
-
- @return length of the message digest
+ * Returns the length of the digest in bytes, or <code>0</code> if this
+ * operation is not supported by the provider and the implementation is not
+ * cloneable.
+ *
+ * @return the digest length in bytes, or <code>0</code> if this operation is
+ * not supported by the provider and the implementation is not cloneable.
+ * @since 1.2
*/
public final int getDigestLength()
{
@@ -320,15 +365,11 @@ public abstract class MessageDigest extends MessageDigestSpi
}
/**
- Returns a clone of this class if supported.
- If it does not then it throws CloneNotSupportedException.
- The cloning of this class depends on whether the subclass
- MessageDigestSpi implements Cloneable which contains the
- actual implementation of the appropriate algorithm.
-
- @return clone of this class
-
- @exception CloneNotSupportedException this class does not support cloning
+ * Returns a clone if the implementation is cloneable.
+ *
+ * @return a clone if the implementation is cloneable.
+ * @throws CloneNotSupportedException if this is called on an implementation
+ * that does not support {@link Cloneable}.
*/
public Object clone() throws CloneNotSupportedException
{
@@ -359,5 +400,4 @@ public abstract class MessageDigest extends MessageDigestSpi
return buf.toString();
}
-
}