www.pudn.com > encryption.rar > HashInputStream.java


/*
Christoforos Pirillos @ Villanova University - May 1999
based on code from the book "Java Network Programming" by Hughes
*/

package encryption;
import java.io.*;

/**This class provides the corresponding integrity-checking reading class
for a hashed stream. It attaches to an InputStream and verifies the data
that arrive on this stream, using a hash function*/

public class HashInputStream extends InputStream {

protected ByteArrayInputStream byteI;
protected DataInputStream dataI;
protected Hash h;

/**The InputStream to be read. Hash to be used*/

public HashInputStream (InputStream i, Hash h) {
	dataI = new DataInputStream (i);
	this.h = h;
	byte[] nothing = new byte[0];
	byteI = new ByteArrayInputStream (nothing);
}

/**reads a single byte from the InputStream.*/

public int read() throws IOException {
	if (available() ==0)
		readHashed();
	return byteI.read();
}

/**reads a subarray of bytes from the InputStream*/

public int read (byte[] b, int o, int l) throws IOException {
	if (available()==0)
		readHashed();
	return byteI.read (b,o,l);
}

/**returns the number of bytes that are currently available in the
InputStream buffer*/

public int available () throws IOException {
	return byteI.available();
}

/**attempts to skip over the specified number of bytes*/

public long skip (long n) throws IOException {
	if (available()==0)
		readHashed();
	return byteI.skip(n);
}

public void close () throws IOException {
	dataI.close();
}

/**Reads a new message from DataInputStream and then verifies that it is
not corrupt by checking the received digest against one computed from the
received message */

protected void readHashed () throws IOException {
	int n;
	try {
		n=dataI.readInt();
	}catch (EOFException ex) {
	return;
	}
	byte[] buffer = new byte[n];
	dataI.readFully(buffer,0,n);
	byte[] digest = new byte[h.digestSize()];
	byte[] newDigest = h.digest(buffer);
	dataI.readFully(digest);
	
	if (!Crypt.equals (digest, newDigest) )
		throw new HashException (h.getClass().getName() +
		" digest check failed.");
	byteI = new ByteArrayInputStream (buffer);
}

} /* end of class HashInputStream */