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.java328
1 files changed, 250 insertions, 78 deletions
diff --git a/libjava/java/security/MessageDigest.java b/libjava/java/security/MessageDigest.java
index 04546cd..d8f6b06 100644
--- a/libjava/java/security/MessageDigest.java
+++ b/libjava/java/security/MessageDigest.java
@@ -1,144 +1,316 @@
-// MessageDigest.java
+/* MessageDigest.java --- The message digest interface.
+ Copyright (C) 1999 Free Software Foundation, Inc.
-/* Copyright (C) 2000 Free Software Foundation
+This file is part of GNU Classpath.
- This file is part of libgcj.
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
-package java.security;
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
-/**
- * @author Tom Tromey <tromey@cygnus.com>
- * @date February 11, 2000.
- */
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
-/**
- * Written using on-line Java Platform 1.1 API Specification.
- * Status: Believed complete and correct to 1.1 spec.
- * It is known not to comply with the 1.2 spec.
- */
+package java.security;
-public abstract class MessageDigest
+public abstract class MessageDigest extends MessageDigestSpi
{
- protected MessageDigest (String algorithm)
+ private String algorithm;
+ private Provider provider;
+ private byte[] lastDigest;
+
+ /**
+ Creates a MessageDigest representing the specified
+ algorithm.
+
+ @param algorithm the name of digest algorithm to choose
+ */
+ protected MessageDigest(String algorithm)
{
- name = algorithm;
+ this.algorithm = algorithm;
+ provider = null;
}
- public static MessageDigest getInstance (String algorithm)
+ /**
+ 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
+ */
+ public static MessageDigest getInstance(String algorithm)
throws NoSuchAlgorithmException
{
+ Provider[] p = Security.getProviders();
String name = "MessageDigest." + algorithm;
- Provider[] provs = Security.getProviders ();
- for (int i = 0; i < provs.length; ++i)
+
+ for (int i = 0; i < p.length; i++)
{
- String val = provs[i].getProperty (name);
- if (val != null)
- {
- try
- {
- return (MessageDigest) Class.forName(val).newInstance ();
- }
- catch (Throwable _)
- {
- // We just ignore failures.
- }
- }
+ String classname = p[i].getProperty(name);
+ if (classname != null)
+ return getInstance(classname, algorithm, p[i]);
}
- throw new NoSuchAlgorithmException (algorithm);
+ throw new NoSuchAlgorithmException(algorithm);
}
- public static MessageDigest getInstance (String algorithm, String provider)
+ /**
+ 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
+ */
+
+ public static MessageDigest getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException
{
- String name = "MessageDigest." + algorithm;
- Provider p = Security.getProvider (provider);
+ Provider p = Security.getProvider(provider);
+
if (p == null)
- throw new NoSuchProviderException (provider);
- String val = p.getProperty (name);
- if (val != null)
+ throw new NoSuchProviderException(provider);
+
+ return getInstance(p.getProperty("MessageDigest." + algorithm),
+ algorithm, p);
+ }
+
+ private static MessageDigest getInstance(String classname,
+ String algorithm,
+ Provider provider)
+ throws NoSuchAlgorithmException
+ {
+ if (classname == null)
+ throw new NoSuchAlgorithmException(algorithm);
+
+ try
+ {
+ MessageDigest m =
+ (MessageDigest) Class.forName(classname).newInstance();
+ m.algorithm = algorithm;
+ m.provider = provider;
+ return m;
+ }
+ catch (ClassNotFoundException cnfe)
+ {
+ throw new NoSuchAlgorithmException(algorithm + ": Class not found.");
+ }
+ catch (InstantiationException ie)
{
- try
- {
- return (MessageDigest) Class.forName(val).newInstance ();
- }
- catch (Throwable _)
- {
- // Nothing.
- }
+ throw new NoSuchAlgorithmException(algorithm
+ + ": Class instantiation failed.");
}
+ catch (IllegalAccessException iae)
+ {
+ throw new NoSuchAlgorithmException(algorithm + ": Illegal Access");
+ }
+ }
+
- throw new NoSuchAlgorithmException (algorithm);
+ /**
+ Gets the provider that the MessageDigest is from.
+
+ @return the provider the this MessageDigest
+ */
+ public final Provider getProvider()
+ {
+ return provider;
}
- public void update (byte input)
+ /**
+ Updates the digest with the byte.
+
+ @param input byte to update the digest with
+ */
+ public void update(byte input)
{
- engineUpdate (input);
+ engineUpdate(input);
}
- public void update (byte[] input, int offset, int len)
+ /**
+ 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
+ */
+ public void update(byte[]input, int offset, int len)
{
- engineUpdate (input, offset, len);
+ engineUpdate(input, 0, input.length);
}
- public void update (byte[] input)
+ /**
+ Updates the digest with the bytes from the array.
+
+ @param input bytes to update the digest with
+ */
+ public void update(byte[]input)
{
- engineUpdate (input, 0, input.length);
+ engineUpdate(input, 0, input.length);
}
- public byte[] digest ()
+ /**
+ Computes the digest of the stored data.
+
+ @return a byte array representing the message digest
+ */
+ public byte[] digest()
+ {
+ return lastDigest = engineDigest();
+ }
+
+ /**
+ 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
+ */
+ public int digest(byte[]buf, int offset, int len) throws DigestException
{
- return engineDigest ();
+ return engineDigest(buf, offset, len);
}
- public byte[] digest (byte[] input)
+ /**
+ 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 buf An array of bytes to perform final update with
+ @return a byte array representing the message digest
+ */
+ public byte[] digest(byte[]input)
{
- update (input);
- return engineDigest ();
+ update(input);
+ return digest();
}
- public String toString ()
+ /**
+ Returns a representation of the MessageDigest as a String.
+
+ @return a string representing the message digest
+ */
+ public String toString()
{
- // There is no spec for this.
- return "[MessageDigest: " + name + "]";
+ return (getClass()).getName()
+ + " Message Digest <" + digestToString() + ">";
}
- public static boolean isEqual (byte[] digesta, byte[] digestb)
+ /**
+ 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
+ */
+ public static boolean isEqual(byte[]digesta, byte[]digestb)
{
- if (digesta == digestb)
- return true;
if (digesta.length != digestb.length)
return false;
+
for (int i = digesta.length - 1; i >= 0; --i)
if (digesta[i] != digestb[i])
return false;
+
return true;
}
- public void reset ()
+
+ /**
+ Resets the message digest.
+ */
+ 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.
+ */
+ public final String getAlgorithm()
{
- engineReset ();
+ return algorithm;
}
- public final String getAlgorithm ()
+ /**
+ 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
+ */
+ public final int getDigestLength()
{
- return name;
+ return engineGetDigestLength();
}
- protected abstract void engineUpdate (byte input);
- protected abstract void engineUpdate (byte input[], int offset, int len);
- protected abstract byte[] engineDigest ();
- protected abstract void engineReset ();
+ /**
+ 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
+ */
public Object clone() throws CloneNotSupportedException
{
- return super.clone ();
+ if (this instanceof Cloneable)
+ return super.clone();
+ else
+ throw new CloneNotSupportedException();
+ }
+
+ private String digestToString()
+ {
+ byte[] digest = lastDigest;
+
+ if (digest == null)
+ return "incomplete";
+
+ StringBuffer buf = new StringBuffer();
+ int len = digest.length;
+ for (int i = 0; i < len; ++i)
+ {
+ byte b = digest[i];
+ byte high = (byte) ((b & 0xff) >>> 4);
+ byte low = (byte) (b & 0xf);
+
+ buf.append(high > 9 ? ('a' - 10) + high : '0' + high);
+ buf.append(low > 9 ? ('a' - 10) + low : '0' + low);
+ }
+
+ return buf.toString();
}
- // Algorithm name.
- private String name;
}