Index: libraries/javalib/java/security/MessageDigest.java =================================================================== RCS file: /cvs/kaffe/kaffe/libraries/javalib/java/security/MessageDigest.java,v retrieving revision 1.4 diff -u -r1.4 MessageDigest.java --- libraries/javalib/java/security/MessageDigest.java 20 Feb 2003 13:52:09 -0000 1.4 +++ libraries/javalib/java/security/MessageDigest.java 12 May 2003 17:42:19 -0000 @@ -19,16 +19,23 @@ // Note: it is a historical screwup that this class extends MessageDigestSpi. // It should not but does. Unfortunately, MessageDigestSpi is abstract, and -// this class inherits that abstractness. That is why we must be able to -// cast the engine we get from the provider to a MessageDigest object instead -// of a MessageDigestSpi object (see ***note below). Normally this class -// would keep an instance of MessageDigestSpi in a private field, but instead -// 'this' is that instance, so we don't need a separate field for it. +// this class inherits that abstractness. As a consequence, a number of classes +// that should extend MessageDigestSpi extend MessageDigest instead. + +// On the other hand, *some* classes that should extend MessageDigestSpi +// *do* extend it. We need to handle that too. + +// Therefore, this class proxies all calls to its engine-- but the engine is, +// by default, 'this'. When we need to construct a MessageDigest object +// wrapping a MessageDigestSpi object, we use a concrete subclass of +// MessageDigest, NonSpiMessageDigest, and change its 'engine' field +// to the actual MessageDigestSpi. Calling engine methods on a +// NonSpiMessageDigest object throws an UnsupportedOperationException. public abstract class MessageDigest extends MessageDigestSpi { private static final String ENGINE_CLASS = "MessageDigest"; private final String algorithm; - /** private MessageDigestSpi engine; **/ + private MessageDigestSpi engine = this; private Provider provider; protected MessageDigest(String algorithm) { @@ -49,9 +56,13 @@ } private static MessageDigest getInstance(Security.Engine e) { - MessageDigest md = (MessageDigest)e.getEngine(); // ***note - // should be: md = new MessageDigest(e.algorithm); - /** md.engine = (MessageDigestSpi)e.engine; **/ + if(o instanceof MessageDigest) { + md = (MessageDigest)o; + } else { + md = new NonSpiMessageDigest(e.algorithm); + md.engine = (MessageDigestSpi)o; + } + md.provider = e.getProvider(); return md; } @@ -61,11 +72,11 @@ } public void update(byte input) { - /*engine.*/engineUpdate(input); + engine.engineUpdate(input); } public void update(byte[] input, int offset, int len) { - /*engine.*/engineUpdate(input, offset, len); + engine.engineUpdate(input, offset, len); } public void update(byte[] input) { @@ -73,14 +84,14 @@ } public byte[] digest() { - byte[] rtn = /*engine.*/engineDigest(); - /*engine.*/engineReset(); + byte[] rtn = engine.engineDigest(); + engine.engineReset(); return rtn; } public int digest(byte[] buf, int offset, int len) throws DigestException { - int digestLen = /*engine.*/engineGetDigestLength(); + int digestLen = engine.engineGetDigestLength(); if (len < digestLen) { throw new DigestException("buf.length < " + digestLen); } @@ -103,7 +114,7 @@ } public void reset() { - /*engine.*/engineReset(); + engine.engineReset(); } public final String getAlgorithm() { @@ -111,11 +122,37 @@ } public final int getDigestLength() { - return /*engine.*/engineGetDigestLength(); + return engine.engineGetDigestLength(); } public Object clone() throws CloneNotSupportedException { return super.clone(); + } + + private static String NONSPI_MSG = + "This MessageDigest is not a MessageDigestSpi. "+ + "MessageDigestSpi methods should not be used "+ + "on MessageDigest objects."; + + private class NonSpiMessageDigest extends MessageDigest { + protected int engineGetDigestLength() { + throw UnsupportedOperationException(NONSPI_MSG); + } + protected void engineUpdate(byte input) { + throw UnsupportedOperationException(NONSPI_MSG); + } + protected void engineUpdate(byte[] input, int offset, int len) { + throw UnsupportedOperationException(NONSPI_MSG); + } + protected byte[] engineDigest() { + throw UnsupportedOperationException(NONSPI_MSG); + } + protected int engineDigest(byte[] buf, int offset, int len) { + throw UnsupportedOperationException(NONSPI_MSG); + } + protected void engineReset() { + throw UnsupportedOperationException(NONSPI_MSG); + } } }