diff options
Diffstat (limited to 'libjava/java/security/MessageDigest.java')
-rw-r--r-- | libjava/java/security/MessageDigest.java | 328 |
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; } |